/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * SocialValuesSliderPanel.java
 *
 * Created on Aug 12, 2009, 7:17:16 PM
 */
package SocialValueSliderPackage;

import DragBarPanelPackage.DragBarButton;
import DragBarPanelPackage.DragBarPanel;
import ExpandablePopupMenuPackage.ExpandablePopupMenu;
import multiarray.MultiArray;
import SocialMatrixPackage.SocialMatrix;
import ccpv.NamedArrayList;
import ccpv.RunTimeSettings;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.Vector;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;

/**
 *
 * @author Heather
 */
public class SocialValuesSliderPanel extends javax.swing.JPanel
{

  /** Creates new form SocialValuesSliderPanel */
  public SocialValuesSliderPanel(JTree inputAscriptiveTree)
  {
    ascriptiveTree = inputAscriptiveTree;
    initComponents();
    // setup the matrix at least until the user changes it
    currentAltruismMatrix = new SocialMatrix(ascriptiveTree);
    // setting up population based on this initial tree
    populationCounts = new HashMap<Integer, MultiArray<Integer>>();
    // setting up the wealth array
    wealthCounts = new MultiArray(currentAltruismMatrix.getDimensions());
    // testing the set method
    currentAltruismMatrix.setAllToValue(0);
    // initialize popup menu
    expMenu = new ExpandablePopupMenu(ascriptiveTree);
    dragBarContainer.setSize(DEFAULT_DRAG_BAR_CONTAINER_SIZE);
    theDragBarPanel.setSize(dragBarContainer.getSize());
    Dimension size = dragBarContainer.getSize();
    dragBarContainer.add(theDragBarPanel);
    dragBarPanels.add(theDragBarPanel);
    setupTreeListeners();
    // add listeners to the menus
    addPopupMouseListeners();
    setupListenersForDragBarButtons();
    setupToolTips();
    // add listeners to altruism scroll bars
    setupAltruismScrollBarListeners();
    // disable all drag bar buttons on altruism panel until user selects categories
    //setEnabledAllAltruismButtons(false);
    // also make all buttons invisible
    setVisibleAllAltruismButtons(false);
    // add popup listener to the tab containing the initial drag bar panel
    addRightClickPopupMenuListenerToTabbedPane();
    System.out.println("the size of scroll pane: " + canvasScrollPane.getSize());
    System.out.println("the preferred size of scroll pane: " + canvasScrollPane.getPreferredSize());
    // setting up altruism default populations
    //setupTestPopulation();
    // setup group details dialog
    groupDetailsDialog.add(gDP);
    gDP.setSize(GroupDetailsPanel.getDEFAULT_SIZE());
    gDP.setPreferredSize(GroupDetailsPanel.getDEFAULT_SIZE());
    groupDetailsDialog.setSize(GroupDetailsPanel.getDEFAULT_SIZE());
    groupDetailsDialog.setPreferredSize(GroupDetailsPanel.getDEFAULT_SIZE());
    setupDetailsPanelListeners();
    // make sure the help stuff is ready
    instructionsTextPane.setText(instructions);
    // comment these out if testing is needed
    jButton1.setVisible(false);
    jButton1.setEnabled(false);
    jButton2.setVisible(false);
    jButton2.setEnabled(false);
    notesTitleLabel.setVisible(false);
    socialValueNotesTextPane.setVisible(false);
    notesContainer.setVisible(false);
    testIndicesButton.setVisible(false);
  //socialValueLoadButton.setVisible(false);
  }

  public void setRunTimeSettings(RunTimeSettings rt)
  {
    this.rt = rt;

    // first setup the ascriptive trees
    setAllAscriptiveTrees(rt.ascriptive_names);

    // now make sure the index map is setup
    setupIndexMapsForTranslation();

    // iterate through the years and load values
    int[] years = rt.getYears();

    for (Integer year : years)
    {
      // load alt values
      SocialMatrix sm = new SocialMatrix(ascriptiveTree);
      altruismMatrices.put(year, sm);
      Vector<int[]> allCombos = sm.getAllCombinations();
      System.out.println("TESTING SM!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
      for (int[] c : allCombos)
      {
        if (c[0] == 0 && c[1] == 0)
        {
          Vector<String> names = sm.convertIndexIntoStringVector(c);
          String p = "";
          for (String s : names)
          {
            p += s + ", ";
          }
          System.out.println(p);
        }
      }

      for (int[] source : allCombos)
      {
        for (int[] target : allCombos)
        {
          double altValue = 0;
          altValue = rt.getAltruism(source, target, year);

          //int[] mySource = rToEIndexMap.get(source);
          //int[] myTarget = rToEIndexMap.get(target);

          //if (mySource == null || myTarget == null)
          //  System.out.println("translation error!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
          //sm.setAltruism(mySource, myTarget, altValue);
          sm.setAltruism(source, target, altValue);
        }
      }

      // load pop values
      MultiArray<Integer> yearPop = new MultiArray<Integer>(sm.getDimensions());
      for (int[] group : allCombos)
      {
        yearPop.setElementAtIndex(group, rt.getPopulation(year, group));
      }
      populationCounts.put(year, yearPop);
    }
  }

  // sets all the trees according to the input.
  // CURRENTLY DOES NOT HANDLE HEIERARCHIES
  public void setAllAscriptiveTrees(List<NamedArrayList<String>> ascriptives)
  {
    ascriptiveCategories = new Vector<String>();

    // all the roots
    DefaultMutableTreeNode tree1Root = (DefaultMutableTreeNode) ascriptiveTree.getModel().getRoot();
    DefaultMutableTreeNode tree2Root = (DefaultMutableTreeNode) socialValueTargetTree.getModel().getRoot();
    DefaultMutableTreeNode tree5Root = (DefaultMutableTreeNode) socialValueSourceTree.getModel().getRoot();

    tree1Root.removeAllChildren();
    tree2Root.removeAllChildren();
    tree5Root.removeAllChildren();

    // iterate through the ascriptive categories
    for (int i = 0; i < ascriptives.size(); i++)
    {
      NamedArrayList<String> ascriptiveCategory = ascriptives.get(i);
      ascriptiveCategories.add(ascriptiveCategory.name);

      DefaultMutableTreeNode ascriptiveCategoryNode1 = new DefaultMutableTreeNode(ascriptiveCategory.name);
      DefaultMutableTreeNode ascriptiveCategoryNode2 = new DefaultMutableTreeNode(ascriptiveCategory.name);
      DefaultMutableTreeNode ascriptiveCategoryNode3 = new DefaultMutableTreeNode(ascriptiveCategory.name);
      DefaultMutableTreeNode ascriptiveCategoryNode4 = new DefaultMutableTreeNode(ascriptiveCategory.name);
      DefaultMutableTreeNode ascriptiveCategoryNode5 = new DefaultMutableTreeNode(ascriptiveCategory.name);

      for (int j = 0; j < ascriptiveCategory.size(); j++)
      {
        String categoryEntry = ascriptiveCategory.get(j);

        DefaultMutableTreeNode categoryEntryNode1 = new DefaultMutableTreeNode(categoryEntry);
        DefaultMutableTreeNode categoryEntryNode2 = new DefaultMutableTreeNode(categoryEntry);
        DefaultMutableTreeNode categoryEntryNode3 = new DefaultMutableTreeNode(categoryEntry);
        DefaultMutableTreeNode categoryEntryNode4 = new DefaultMutableTreeNode(categoryEntry);
        DefaultMutableTreeNode categoryEntryNode5 = new DefaultMutableTreeNode(categoryEntry);

        ascriptiveCategoryNode1.add(categoryEntryNode1);
        ascriptiveCategoryNode2.add(categoryEntryNode2);
        ascriptiveCategoryNode3.add(categoryEntryNode3);
        ascriptiveCategoryNode4.add(categoryEntryNode4);
        ascriptiveCategoryNode5.add(categoryEntryNode5);
      }

      tree1Root.add(ascriptiveCategoryNode1);
      tree2Root.add(ascriptiveCategoryNode2);
      tree5Root.add(ascriptiveCategoryNode5);
    }

    ascriptiveTree.updateUI();
    socialValueTargetTree.updateUI();
    socialValueSourceTree.updateUI();

    // if the trees change, we need to change the popup menu too
    expMenu = new ExpandablePopupMenu(ascriptiveTree);
    // the expMenu is new, so add new listeners
    addPopupMouseListeners();
    expMenu.updateUI();

    // also have to change altruism matrix b/c it is dependent on the trees
    altruismMatrices.clear();
    currentAltruismMatrix = new SocialMatrix(ascriptiveTree);
    populationCounts = new HashMap<Integer, MultiArray<Integer>>();
  // TESTING STUFF HERE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  //currentAltruismMatrix.setAllToValue(0.5);
  }

  public void setupDetailsPanelListeners()
  {
    gDP.getGroupDetailsSetPopulationButton().addActionListener(new java.awt.event.ActionListener()
    {

      // currently evenly divides the population among all subgroups.....................................................................................
      public void actionPerformed(java.awt.event.ActionEvent evt)
      {
        Vector<int[]> repGroups = gDP.representedGroups;
        int setPop = Integer.parseInt(gDP.getGroupDetailsPopulationTextPane().getText());
        int popPerGroup = (int) (setPop / repGroups.size());
        for (int[] crossSection : repGroups)
        {
          populationCounts.get(currentYear).setElementAtIndex(crossSection, popPerGroup);
        }
      }
    });

    gDP.getGroupDetailsSetWealthButton().addActionListener(new java.awt.event.ActionListener()
    {

      public void actionPerformed(java.awt.event.ActionEvent evt)
      {
        Vector<int[]> repGroups = gDP.representedGroups;
        int wealth = Integer.parseInt(gDP.getGroupDetailsWealthTextPane().getText());
        for (int[] crossSection : repGroups)
        {
          wealthCounts.setElementAtIndex(crossSection, wealth);
        }
      }
    });
  }

  /** This method is called from within the constructor to
   * initialize the form.
   * WARNING: Do NOT modify this code. The content of this method is
   * always regenerated by the Form Editor.
   */
  @SuppressWarnings("unchecked")
  public void setupTreeListeners()
  {
    // setup tree listeners for altruism dialog
    socialValueTargetTree.addTreeSelectionListener(new TreeSelectionListener()
    {

      public void valueChanged(TreeSelectionEvent e)
      {
        loadTargetTreeValues();
      }
    });

    socialValueSourceTree.addTreeSelectionListener(new TreeSelectionListener()
    {

      public void valueChanged(TreeSelectionEvent e)
      {
        loadSourceTreeValues();
      }
    });
  }

  private void loadTargetTreeValues()
  {
    DragBarPanel currentPanel = this.getCurrentPanel();

    DefaultMutableTreeNode node = (DefaultMutableTreeNode) socialValueTargetTree.getLastSelectedPathComponent();

    /* if nothing is selected */
    if (node == null)
    {
      return;
    }

    /* retrieve the node that was selected */
    Object nodeInfo = node.getUserObject();

    if (yearSet)
    {
      /* React to the node selection. Note that this doesn't take into account hiearchies */
      if (node.isLeaf())
      {
        tabTrackers.clear();
        socialValuesTabbedPane.setTitleAt(0, (String) nodeInfo);
        socialValuesTabbedPane.getComponentAt(0).setName((String) nodeInfo);
        // create a tracker for this tab
        //SocialValueComponentTracker(Component theComponent, Vector<String> ascriptiveCategories,
        //Vector<String> buttonAscriptives, Vector<int[]> representedGroups)
        // category vector for the new trackers
        Vector<String> ascriptiveCategories = new Vector<String>();
        // indicates which ascriptive category the node is
        int nodeIndex = -1;
        // setup the information needed for trackers
        DefaultMutableTreeNode root = (DefaultMutableTreeNode) ascriptiveTree.getModel().getRoot();
        // need the parent to check which category the node came from b/c the node is a leaf
        // CURRENTLY DOES NOT TAKE INTO ACCOUNT HIEARCHIES
        DefaultMutableTreeNode nodeParent = (DefaultMutableTreeNode) node.getParent();
        for (int i = 0; i < root.getChildCount(); i++)
        {
          DefaultMutableTreeNode child = (DefaultMutableTreeNode) root.getChildAt(i);
          String currentChildString = (String) child.getUserObject();
          ascriptiveCategories.add(currentChildString);
          if (currentChildString.equals((String) nodeParent.getUserObject()))
          {
            nodeIndex = i;
          }
        }
        if (nodeIndex == -1)
        {
          System.out.println("AHAH!  located in target tree");
        }

        Vector<String> panelAscriptives = new Vector<String>();
        // this is used for the tracker.  need to set this up now

        for (int j = 0; j < ascriptiveCategories.size(); j++)
        {
          if (j == nodeIndex)
          {
            panelAscriptives.add((String) node.getUserObject());
          }
          else
          {
            panelAscriptives.add(ascriptiveCategories.get(j));
          }
        }

        Vector<int[]> newRepresentedGroups = currentAltruismMatrix.getRepresentedGroups(panelAscriptives);
        System.out.println("DRAG BAR PANEL IS GIVEN A TRACKER");
        SocialValueComponentTracker dragBarPanelTracker = new SocialValueComponentTracker(currentPanel,
                ascriptiveCategories, panelAscriptives, newRepresentedGroups);
        String parentString = (String) (((DefaultMutableTreeNode) node.getParent()).getUserObject());
        dragBarPanelTracker.disabledAltruism.add(parentString);
        tabTrackers.add(dragBarPanelTracker);
        currentPanel.repaint();
        socialValuesSourcesSetup = true;
        if (socialValuesSourcesSetup && socialValuesTargetsSetup && yearSet)
        {
          dragBarContainer.setSize(DEFAULT_DRAG_BAR_CONTAINER_SIZE);
          currentPanel.setSize(DEFAULT_DRAG_BAR_CONTAINER_SIZE);
          setVisibleAllAltruismButtons(true);
          moveButtonsBasedOnAltruism(currentPanel, buttonTrackers.get(socialValuesTabbedPane.getSelectedIndex()), dragBarPanelTracker);
        //dragBarPanels.add(currentPanel);
        }
      }
    }
    else
    {
      yearNotSetDialog.setSize(yearNotSetDialogSize);
      yearNotSetDialog.setPreferredSize(yearNotSetDialogSize);
      yearNotSetDialog.setVisible(true);
    }
  }

  private void loadSourceTreeValues()
  {
    DragBarPanel currentPanel = this.getCurrentPanel();

    System.out.println("hey");
    DefaultMutableTreeNode node = (DefaultMutableTreeNode) socialValueSourceTree.getLastSelectedPathComponent();

    /* if nothing is selected */
    if (node == null)
    {
      return;
    }

    if (yearSet)
    {
      /* React to the node selection. */
      // create buttons if there are children.
      // THIS NEEDS TO BE FIXED WHEN WE DEFINE HIERARCHIES!!!!!
      if (!node.isLeaf())
      {
        // clear the trackers
        buttonTrackers.clear();
        // category vector for the new trackers
        Vector<String> ascriptiveCategories = new Vector<String>();
        // indicates which ascriptive category the node is
        int nodeIndex = -1;
        // setup the information needed for trackers
        DefaultMutableTreeNode root = (DefaultMutableTreeNode) ascriptiveTree.getModel().getRoot();
        for (int i = 0; i < root.getChildCount(); i++)
        {
          DefaultMutableTreeNode child = (DefaultMutableTreeNode) root.getChildAt(i);
          String currentChildString = (String) child.getUserObject();
          ascriptiveCategories.add(currentChildString);
          if (currentChildString.equals((String) node.getUserObject()))
          {
            nodeIndex = i;
          }
        }
        if (nodeIndex == -1)
        {
          System.out.println("AHAH!  located in SOURCE tree");
        }

        Vector<DragBarButton> currentDragBarButtons = currentPanel.getButtons();

        // remove any excess buttons first
        int buttonDifference = currentDragBarButtons.size() - node.getChildCount();
        if (buttonDifference > 0)
        {
          for (int i = 0; i < buttonDifference; i++)
          {
            currentPanel.removeAButton(0);
          }
        }

        // create buttons for each child
        // since this is the first time the user selects, we need to add a new vector
        Vector<SocialValueComponentTracker> firstTrackers = new Vector<SocialValueComponentTracker>();
        buttonTrackers.add(firstTrackers);
        for (int i = 0; i < node.getChildCount(); i++)
        {
          DefaultMutableTreeNode child = (DefaultMutableTreeNode) node.getChildAt(i);
          DragBarButton currentButton;

          // this is used for the tracker.  need to set this up now
          Vector<String> buttonAscriptives = new Vector<String>();

          for (int j = 0; j < ascriptiveCategories.size(); j++)
          {
            if (j == nodeIndex)
            {
              buttonAscriptives.add((String) child.getUserObject());
            }
            else
            {
              buttonAscriptives.add(ascriptiveCategories.get(j));
            }
          }

          // utilize the buttons currently on screen first
          if (i < currentDragBarButtons.size())
          {
            currentButton = currentDragBarButtons.get(i);
          }
          else
          {
            currentButton = currentPanel.addNewButton((String) child.getUserObject());
            addDoubleClickListenerToDragBarButton(currentButton);
            addMenuListenerToDragBarButton(currentButton);
            addLeftClickListenerToDragBarButton(currentButton);
            addDragListenerToDragBarButton(currentButton);//, 0);
          }

          currentButton.setName((String) child.getUserObject());
          currentButton.setText((String) child.getUserObject());
          currentButton.setVisible(false);
          currentButton.getTheLabel().setVisible(false);
          // create a tracker for this button
          Vector<int[]> newRepresentedGroups = currentAltruismMatrix.getRepresentedGroups(buttonAscriptives);
          SocialValueComponentTracker newTracker = new SocialValueComponentTracker(currentButton, ascriptiveCategories, buttonAscriptives, newRepresentedGroups);
          if (currentButton.getName() == null)
          {
            System.out.println("the name of currentButton is null!!!!!!!!!!!!!!!  LINE 1448");
          }
          newTracker.disabledAltruism.add((String) node.getUserObject());

          firstTrackers.add(newTracker);
          firstTrackersSetup = true;

        // disable buttons that don't have a population
        //setEnabledAllAltruismButtons(true);
        //setEnabledAllZeroPopulationAltruismButtons(false);
        }

        currentPanel.updateUI();

        socialValuesTargetsSetup = true;
        if (socialValuesSourcesSetup && socialValuesTargetsSetup && yearSet)
        {
          dragBarContainer.setSize(DEFAULT_DRAG_BAR_CONTAINER_SIZE);
          currentPanel.setSize(DEFAULT_DRAG_BAR_CONTAINER_SIZE);
          setVisibleAllAltruismButtons(true);
          moveButtonsBasedOnAltruism(currentPanel, buttonTrackers.get(socialValuesTabbedPane.getSelectedIndex()), tabTrackers.get(socialValuesTabbedPane.getSelectedIndex()));
        //dragBarPanels.add(currentPanel);
        }
      }
    }
    else
    {
      yearNotSetDialog.setSize(yearNotSetDialogSize);
      yearNotSetDialog.setPreferredSize(yearNotSetDialogSize);
      yearNotSetDialog.setVisible(true);
    }

  }


  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
  private void initComponents() {

    fileChooser = new javax.swing.JFileChooser();
    groupDetailsDialog = new javax.swing.JDialog();
    yearNotSetDialog = new javax.swing.JDialog();
    jPanel2 = new javax.swing.JPanel();
    jLabel2 = new javax.swing.JLabel();
    helpDialog = new javax.swing.JDialog();
    jPanel3 = new javax.swing.JPanel();
    jLabel3 = new javax.swing.JLabel();
    jScrollPane1 = new javax.swing.JScrollPane();
    instructionsTextPane = new javax.swing.JTextArea();
    jLabel5 = new javax.swing.JLabel();
    jLabel7 = new javax.swing.JLabel();
    jLabel8 = new javax.swing.JLabel();
    saveCompleteDialog = new javax.swing.JDialog();
    jPanel4 = new javax.swing.JPanel();
    jLabel4 = new javax.swing.JLabel();
    fileErrorDialog = new javax.swing.JDialog();
    jPanel5 = new javax.swing.JPanel();
    jLabel6 = new javax.swing.JLabel();
    jLabel17 = new javax.swing.JLabel();
    jScrollPane12 = new javax.swing.JScrollPane();
    socialValueTargetTree = new javax.swing.JTree();
    jScrollPane13 = new javax.swing.JScrollPane();
    socialValueSourceTree = new javax.swing.JTree();
    jPanel1 = new javax.swing.JPanel();
    socialValueTitle = new javax.swing.JLabel();
    socialValuesTabbedPane = new javax.swing.JTabbedPane();
    firstAltruismPanel = new javax.swing.JPanel();
    movingPanel = new javax.swing.JPanel();
    canvasScrollPane = new javax.swing.JScrollPane();
    dragBarContainer = new javax.swing.JPanel();
    jLabel21 = new javax.swing.JLabel();
    yAxisScaleInputText = new javax.swing.JTextField();
    yAxisScaleOKButton = new javax.swing.JButton();
    socialValueSaveButton = new javax.swing.JButton();
    notesContainer = new javax.swing.JScrollPane();
    socialValueNotesTextPane = new javax.swing.JTextPane();
    sortByChildrenButton = new javax.swing.JButton();
    jLabel18 = new javax.swing.JLabel();
    notesTitleLabel = new javax.swing.JLabel();
    jButton1 = new javax.swing.JButton();
    jButton2 = new javax.swing.JButton();
    yearTextField = new javax.swing.JTextField();
    jLabel1 = new javax.swing.JLabel();
    setYearButton = new javax.swing.JButton();
    socialValueLoadButton = new javax.swing.JButton();
    helpButton = new javax.swing.JButton();
    testIndicesButton = new javax.swing.JButton();

    javax.swing.GroupLayout groupDetailsDialogLayout = new javax.swing.GroupLayout(groupDetailsDialog.getContentPane());
    groupDetailsDialog.getContentPane().setLayout(groupDetailsDialogLayout);
    groupDetailsDialogLayout.setHorizontalGroup(
      groupDetailsDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGap(0, 854, Short.MAX_VALUE)
    );
    groupDetailsDialogLayout.setVerticalGroup(
      groupDetailsDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGap(0, 589, Short.MAX_VALUE)
    );

    yearNotSetDialog.getContentPane().setLayout(null);

    jPanel2.setBackground(new java.awt.Color(255, 204, 204));
    jPanel2.setLayout(null);

    jLabel2.setBackground(new java.awt.Color(255, 204, 204));
    jLabel2.setFont(new java.awt.Font("Tahoma", 3, 14));
    jLabel2.setText("Need to specify year first!");
    jPanel2.add(jLabel2);
    jLabel2.setBounds(40, 20, 176, 17);

    yearNotSetDialog.getContentPane().add(jPanel2);
    jPanel2.setBounds(0, 0, 250, 90);

    jPanel3.setBackground(new java.awt.Color(255, 255, 204));
    jPanel3.setLayout(null);

    jLabel3.setFont(new java.awt.Font("Tahoma", 3, 14));
    jLabel3.setText("Instructions");
    jPanel3.add(jLabel3);
    jLabel3.setBounds(10, 10, 100, 30);

    instructionsTextPane.setColumns(20);
    instructionsTextPane.setEditable(false);
    instructionsTextPane.setFont(new java.awt.Font("Times New Roman", 1, 16));
    instructionsTextPane.setForeground(new java.awt.Color(0, 0, 153));
    instructionsTextPane.setRows(5);
    jScrollPane1.setViewportView(instructionsTextPane);

    jPanel3.add(jScrollPane1);
    jScrollPane1.setBounds(10, 40, 590, 310);

    jLabel5.setFont(new java.awt.Font("Tahoma", 3, 14));
    jLabel5.setText("Tips");
    jPanel3.add(jLabel5);
    jLabel5.setBounds(10, 360, 80, 20);

    jLabel7.setFont(new java.awt.Font("Tahoma", 1, 14));
    jLabel7.setText("* Right click on buttons or tabs to define exceptions.");
    jPanel3.add(jLabel7);
    jLabel7.setBounds(10, 390, 590, 20);

    jLabel8.setFont(new java.awt.Font("Tahoma", 1, 14)); // NOI18N
    jLabel8.setText("* When saving or loading, just select the directory of the files.");
    jPanel3.add(jLabel8);
    jLabel8.setBounds(10, 420, 590, 20);

    javax.swing.GroupLayout helpDialogLayout = new javax.swing.GroupLayout(helpDialog.getContentPane());
    helpDialog.getContentPane().setLayout(helpDialogLayout);
    helpDialogLayout.setHorizontalGroup(
      helpDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, 612, Short.MAX_VALUE)
    );
    helpDialogLayout.setVerticalGroup(
      helpDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, 467, Short.MAX_VALUE)
    );

    jPanel4.setBackground(new java.awt.Color(204, 255, 204));
    jPanel4.setLayout(null);

    jLabel4.setBackground(new java.awt.Color(255, 204, 204));
    jLabel4.setFont(new java.awt.Font("Tahoma", 3, 14));
    jLabel4.setText("Save Complete!");
    jPanel4.add(jLabel4);
    jLabel4.setBounds(40, 20, 120, 17);

    javax.swing.GroupLayout saveCompleteDialogLayout = new javax.swing.GroupLayout(saveCompleteDialog.getContentPane());
    saveCompleteDialog.getContentPane().setLayout(saveCompleteDialogLayout);
    saveCompleteDialogLayout.setHorizontalGroup(
      saveCompleteDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGap(0, 400, Short.MAX_VALUE)
      .addGroup(saveCompleteDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE))
    );
    saveCompleteDialogLayout.setVerticalGroup(
      saveCompleteDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGap(0, 300, Short.MAX_VALUE)
      .addGroup(saveCompleteDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE))
    );

    jPanel5.setBackground(new java.awt.Color(255, 204, 204));
    jPanel5.setLayout(null);

    jLabel6.setBackground(new java.awt.Color(255, 204, 204));
    jLabel6.setFont(new java.awt.Font("Tahoma", 3, 14)); // NOI18N
    jLabel6.setText("Error in file IO!");
    jPanel5.add(jLabel6);
    jLabel6.setBounds(40, 20, 120, 17);

    javax.swing.GroupLayout fileErrorDialogLayout = new javax.swing.GroupLayout(fileErrorDialog.getContentPane());
    fileErrorDialog.getContentPane().setLayout(fileErrorDialogLayout);
    fileErrorDialogLayout.setHorizontalGroup(
      fileErrorDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGap(0, 400, Short.MAX_VALUE)
      .addGroup(fileErrorDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addComponent(jPanel5, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE))
    );
    fileErrorDialogLayout.setVerticalGroup(
      fileErrorDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGap(0, 300, Short.MAX_VALUE)
      .addGroup(fileErrorDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addComponent(jPanel5, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE))
    );

    setBackground(new java.awt.Color(204, 255, 204));
    setLayout(null);

    jLabel17.setFont(new java.awt.Font("Tahoma", 1, 14));
    jLabel17.setText("Source");
    add(jLabel17);
    jLabel17.setBounds(10, 290, 60, 17);

    jScrollPane12.setViewportView(socialValueTargetTree);

    add(jScrollPane12);
    jScrollPane12.setBounds(10, 110, 130, 170);

    jScrollPane13.setViewportView(socialValueSourceTree);

    add(jScrollPane13);
    jScrollPane13.setBounds(10, 310, 130, 180);

    jPanel1.setBackground(new java.awt.Color(255, 255, 255));

    socialValueTitle.setFont(new java.awt.Font("Tahoma", 1, 24));
    socialValueTitle.setText("Group Altruism");

    socialValuesTabbedPane.setBackground(new java.awt.Color(255, 255, 204));
    socialValuesTabbedPane.addChangeListener(new javax.swing.event.ChangeListener() {
      public void stateChanged(javax.swing.event.ChangeEvent evt) {
        socialValuesTabbedPaneStateChanged(evt);
      }
    });

    canvasScrollPane.setBorder(null);
    canvasScrollPane.setAutoscrolls(true);
    canvasScrollPane.addMouseListener(new java.awt.event.MouseAdapter() {
      public void mouseEntered(java.awt.event.MouseEvent evt) {
        canvasScrollPaneMouseEntered(evt);
      }
    });
    canvasScrollPane.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
      public void mouseDragged(java.awt.event.MouseEvent evt) {
        canvasScrollPaneMouseDragged(evt);
      }
    });

    dragBarContainer.setBackground(new java.awt.Color(255, 255, 255));
    dragBarContainer.setMinimumSize(new java.awt.Dimension(490, 440));
    dragBarContainer.addMouseListener(new java.awt.event.MouseAdapter() {
      public void mouseEntered(java.awt.event.MouseEvent evt) {
        dragBarContainerMouseEntered(evt);
      }
      public void mouseExited(java.awt.event.MouseEvent evt) {
        dragBarContainerMouseExited(evt);
      }
    });
    dragBarContainer.setLayout(null);
    canvasScrollPane.setViewportView(dragBarContainer);

    javax.swing.GroupLayout movingPanelLayout = new javax.swing.GroupLayout(movingPanel);
    movingPanel.setLayout(movingPanelLayout);
    movingPanelLayout.setHorizontalGroup(
      movingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addComponent(canvasScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 644, Short.MAX_VALUE)
    );
    movingPanelLayout.setVerticalGroup(
      movingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addComponent(canvasScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 547, Short.MAX_VALUE)
    );

    javax.swing.GroupLayout firstAltruismPanelLayout = new javax.swing.GroupLayout(firstAltruismPanel);
    firstAltruismPanel.setLayout(firstAltruismPanelLayout);
    firstAltruismPanelLayout.setHorizontalGroup(
      firstAltruismPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(firstAltruismPanelLayout.createSequentialGroup()
        .addComponent(movingPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
    );
    firstAltruismPanelLayout.setVerticalGroup(
      firstAltruismPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addComponent(movingPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
    );

    socialValuesTabbedPane.addTab("tab1", firstAltruismPanel);

    javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
    jPanel1.setLayout(jPanel1Layout);
    jPanel1Layout.setHorizontalGroup(
      jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(jPanel1Layout.createSequentialGroup()
        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
          .addComponent(socialValuesTabbedPane, javax.swing.GroupLayout.DEFAULT_SIZE, 650, Short.MAX_VALUE)
          .addGroup(jPanel1Layout.createSequentialGroup()
            .addGap(188, 188, 188)
            .addComponent(socialValueTitle)))
        .addContainerGap())
    );
    jPanel1Layout.setVerticalGroup(
      jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(jPanel1Layout.createSequentialGroup()
        .addComponent(socialValueTitle)
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addComponent(socialValuesTabbedPane, javax.swing.GroupLayout.DEFAULT_SIZE, 575, Short.MAX_VALUE))
    );

    add(jPanel1);
    jPanel1.setBounds(150, 10, 650, 610);

    jLabel21.setFont(new java.awt.Font("Tahoma", 1, 14));
    jLabel21.setText("Y Axis Scale");
    add(jLabel21);
    jLabel21.setBounds(10, 500, 90, 17);

    yAxisScaleInputText.setText("1.0");
    yAxisScaleInputText.addMouseListener(new java.awt.event.MouseAdapter() {
      public void mouseEntered(java.awt.event.MouseEvent evt) {
        yAxisScaleInputTextMouseEntered(evt);
      }
    });
    add(yAxisScaleInputText);
    yAxisScaleInputText.setBounds(10, 520, 130, 20);

    yAxisScaleOKButton.setText("Set Y Axis Scale");
    yAxisScaleOKButton.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        yAxisScaleOKButtonActionPerformed(evt);
      }
    });
    add(yAxisScaleOKButton);
    yAxisScaleOKButton.setBounds(10, 540, 130, 30);

    socialValueSaveButton.setText("Save");
    socialValueSaveButton.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        socialValueSaveButtonActionPerformed(evt);
      }
    });
    add(socialValueSaveButton);
    socialValueSaveButton.setBounds(10, 580, 130, 30);

    notesContainer.setViewportView(socialValueNotesTextPane);

    add(notesContainer);
    notesContainer.setBounds(810, 70, 170, 550);

    sortByChildrenButton.setText("Sort buttons by children");
    sortByChildrenButton.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        sortByChildrenButtonActionPerformed(evt);
      }
    });
    add(sortByChildrenButton);
    sortByChildrenButton.setBounds(150, 620, 220, 23);

    jLabel18.setFont(new java.awt.Font("Tahoma", 1, 14));
    jLabel18.setText("Target");
    add(jLabel18);
    jLabel18.setBounds(10, 90, 70, 17);

    notesTitleLabel.setFont(new java.awt.Font("Tahoma", 3, 12));
    notesTitleLabel.setText("Notes");
    add(notesTitleLabel);
    notesTitleLabel.setBounds(810, 44, 120, 20);

    jButton1.setText("check trackers");
    jButton1.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        jButton1ActionPerformed(evt);
      }
    });
    add(jButton1);
    jButton1.setBounds(680, 620, 120, 23);

    jButton2.setText("test loading");
    jButton2.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        jButton2ActionPerformed(evt);
      }
    });
    add(jButton2);
    jButton2.setBounds(560, 620, 120, 23);
    add(yearTextField);
    yearTextField.setBounds(10, 30, 130, 20);

    jLabel1.setFont(new java.awt.Font("Tahoma", 1, 14));
    jLabel1.setText("Year");
    add(jLabel1);
    jLabel1.setBounds(10, 10, 50, 17);

    setYearButton.setText("Set Year");
    setYearButton.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        setYearButtonActionPerformed(evt);
      }
    });
    add(setYearButton);
    setYearButton.setBounds(10, 50, 130, 30);

    socialValueLoadButton.setText("Load");
    socialValueLoadButton.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        socialValueLoadButtonActionPerformed(evt);
      }
    });
    add(socialValueLoadButton);
    socialValueLoadButton.setBounds(10, 610, 130, 30);

    helpButton.setText("Help");
    helpButton.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        helpButtonActionPerformed(evt);
      }
    });
    add(helpButton);
    helpButton.setBounds(370, 620, 190, 23);

    testIndicesButton.setText("test indices");
    testIndicesButton.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        testIndicesButtonActionPerformed(evt);
      }
    });
    add(testIndicesButton);
    testIndicesButton.setBounds(810, 620, 170, 23);
  }// </editor-fold>//GEN-END:initComponents

  // rearranges the buttons so the children are next to each other
  /*
   * Warning: if there exist buttons that are children of more than one component, this will
   * cause problems.  But that shouldn't happen anyway.
   */
  private void sortButtonsByChildren()
  {
    System.out.println("SORTTING THE CHILDREN!!!!!!!!!!");
    DragBarPanel currentDragBarPanel = dragBarPanels.get(socialValuesTabbedPane.getSelectedIndex());
    Vector<SocialValueComponentTracker> currentButtonTrackers = buttonTrackers.get(socialValuesTabbedPane.getSelectedIndex());
    // stores the children for each button
    Vector<Vector<SocialValueComponentTracker>> childrenList = new Vector<Vector<SocialValueComponentTracker>>(currentButtonTrackers.size());
    // fill in the holes for the childrenList
    for (int i = 0; i < currentButtonTrackers.size(); i++)
    {
      childrenList.add(new Vector<SocialValueComponentTracker>());
    }

    // cycle through button trackers
    for (int i = 0; i < currentButtonTrackers.size(); i++)
    {
      SocialValueComponentTracker parentCandidate = currentButtonTrackers.get(i);
      Vector<SocialValueComponentTracker> currentChildren = childrenList.get(i);

      // for each candidate, find a child if a parent exists
      for (int j = 0; j < currentButtonTrackers.size(); j++)
      {
        SocialValueComponentTracker childCandidate = currentButtonTrackers.get(j);

        // don't want to check if the child is a child of itself
        if (i != j)
        {
          boolean isChild = isChild(childCandidate, parentCandidate);
          if (isChild)
          {
            // before we add this child, make sure it doesn't have a smaller parent
            boolean hasSmallerParent = false;
            for (int k = 0; k < currentButtonTrackers.size(); k++)
            {
              // don't compare k to itself
              if (k != j)
              {
                SocialValueComponentTracker anotherParentCandidate = currentButtonTrackers.get(k);
                int anotherParentCandidateSize = anotherParentCandidate.representedGroups.size();
                int parentCandidateSize = parentCandidate.representedGroups.size();
                if (isChild(childCandidate, anotherParentCandidate) && (anotherParentCandidateSize < parentCandidateSize))
                {
                  hasSmallerParent = true;
                }
              }
            }

            if (hasSmallerParent)
            {
              System.out.println("smaller parent found!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
            }

            if (!hasSmallerParent)
            {
              currentChildren.add(childCandidate);
            }

            System.out.println("parent: " + ((DragBarButton) parentCandidate.theComponent).getName());
            System.out.println("child: " + ((DragBarButton) childCandidate.theComponent).getName());
          }
        }
      }
    }

    // now we have all the children, so we need to move them next to their parents
    // this will store the order of the new buttons so we can rearrange them
    Vector<SocialValueComponentTracker> buttonOrder = new Vector<SocialValueComponentTracker>();

    for (int i = 0; i < currentButtonTrackers.size(); i++)
    {
      SocialValueComponentTracker currentTracker = currentButtonTrackers.get(i);

      // use DFS to add children and tracker.
      Vector<SocialValueComponentTracker> stack = new Vector<SocialValueComponentTracker>();
      stack.add(currentTracker);

      // add children until we're done
      while (stack.size() > 0)
      {
        // pop top
        SocialValueComponentTracker top = stack.get(stack.size() - 1);
        stack.remove(top);

        // add top to buttonOrder
        if (!buttonOrder.contains(top))
        {
          buttonOrder.add(top);
        }

        // add children to stack
        // first we need to find what index this top tracker is on the buttons
        int topIndex = 0;
        for (int j = 0; j < currentButtonTrackers.size(); j++)
        {
          SocialValueComponentTracker t = currentButtonTrackers.get(j);
          if (t.equals(top))
          {
            topIndex = j;
          }
        }

        // w/ the index, we know where to get the top's children
        Vector<SocialValueComponentTracker> topChildren = childrenList.get(topIndex);
        for (int j = 0; j < topChildren.size(); j++)
        {
          stack.add(topChildren.get(j));
        }
      }
    }

    // now that we have the button order, simply rearrange the buttons and their trackers
    // we'll use this to store the old values of the buttons, so we know what to copy
    Vector<DragBarButton> tempStorage = new Vector<DragBarButton>();
    // copy the buttons
    for (int i = 0; i < buttonOrder.size(); i++)
    {
      tempStorage.add(((DragBarButton) buttonOrder.get(i).theComponent).clone());
    }

    Vector<DragBarButton> theButtons = currentDragBarPanel.getButtons();
    System.out.println("Button size: " + theButtons.size());
    System.out.println("order size: " + buttonOrder.size());
    // clear the old trackers b/c we're replacin them
    currentButtonTrackers.clear();
    // make sure that the buttonorder trackers point to the correct buttons
    for (int i = 0; i < buttonOrder.size(); i++)
    {
      // set the current tracker to the button at i
      SocialValueComponentTracker aTracker = buttonOrder.get(i);
      aTracker.theComponent = theButtons.get(i);
      //System.out.println("the aTracker: ");
      //aTracker.printReprsentedGroups();
      //System.out.println("end of tracker");

      // now make sure the current button we have reflects the change
      theButtons.get(i).copy(tempStorage.get(i));
      aTracker.componentName = aTracker.theComponent.getName();

      // lastly, replace the current altruism button trackers w/ button order
      currentButtonTrackers.add(aTracker);
    }

    // finally b/c we adjusted all the buttons, move them to the proper positions
    this.setButtonsOnDragBarPanel(socialValuesTabbedPane.getSelectedIndex());
    currentDragBarPanel.repaint();
  }

  // use this when switching between panels to make sure panels reflect the buttons they have
  // will loop through all tabs
  private void setButtonsOnDragBarPanel(int dragBarPanelIndex)
  {
    int selectedIndex = dragBarPanelIndex;//socialValuesTabbedPane.getSelectedIndex();
    Vector<SocialValueComponentTracker> currentButtonTrackers = buttonTrackers.get(selectedIndex);
    SocialValueComponentTracker targetTracker = tabTrackers.get(selectedIndex);
    DragBarPanel selectedDragBarPanel = dragBarPanels.get(dragBarPanelIndex);

    Vector<DragBarButton> currentButtons = selectedDragBarPanel.getButtons();
    int numberOfNewButtons = currentButtonTrackers.size();
    int buttonDifference = numberOfNewButtons - currentButtons.size();

    // if there are currently more buttons than we need, remove excess
    System.out.println("THIS IS THE button difference: " + buttonDifference);
    if (buttonDifference < 0)
    {
      for (int i = 0; i > buttonDifference; i--)
      {
        selectedDragBarPanel.removeAButton(0);
      }
    }

    // now we add the buttons we need
    currentButtons = selectedDragBarPanel.getButtons();
    for (int i = 0; i < numberOfNewButtons; i++)
    {
      SocialValueComponentTracker currentT = currentButtonTrackers.get(i);
      DragBarButton currentButton = null;

      // first see if we need to make a new button or not
      if (i >= currentButtons.size())
      {
        // make a new button
        currentButton = selectedDragBarPanel.addNewButton("");
      }
      else // else we just use an old button
      {
        currentButton = currentButtons.get(i);
      }
      // make the tracker reflect this button
      currentT.theComponent = currentButton;

      // set the values for used button
      currentButton.setName(currentT.componentName);
      String newText = "<html>";
      // tokenize the old name to find breaks
      StringTokenizer tokenizer = new StringTokenizer(currentT.componentName, ";");
      while (tokenizer.hasMoreTokens())
      {
        newText += tokenizer.nextToken() + "<br>";
      }
      newText += "</html>";
      currentButton.setText(newText);

      Vector<int[]> sources = currentT.representedGroups;
      Vector<int[]> targets = targetTracker.representedGroups;
      // note: this does not include w/ population?!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      //double average = altruismMatrix.getAverageAltruismMultipleSourcesAndTargets(sources, targets);
      MultiArray<Integer> yearCount = populationCounts.get(currentYear);
      // get the population of the button
      int buttonPop = findPopulationForComponent(currentButton, currentYear);
      if (buttonPop <= 0)
        currentButton.setUserDefinedLabel("no population");
      else
        currentButton.setUserDefinedLabel(null);
      double average = currentAltruismMatrix.getAverageAltruismMultipleSourcesAndTargetsWithPopulation(sources, targets, yearCount);
      //double average = 0.2; // testing!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      selectedDragBarPanel.setButtonValueAndMove(currentButton, average);
    }
  }

  /*
   * METHODS SPECIFICALLY FOR ALTRUISM DIALOG
   */

  // sets up right click listeners for drag bar buttons
  // NEED TO CONSIDER REMOVING OR CHANGING THIS METHOD B/C REALLY IT'S ONLY EVER USED ONCE DURING SETUP!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  private void setupListenersForDragBarButtons()
  {
    Vector<DragBarButton> theDBButtons = theDragBarPanel.getButtons();

    for (int i = 0; i < theDBButtons.size(); i++)
    {
      final DragBarButton b = theDBButtons.get(i);
      addDoubleClickListenerToDragBarButton(b);
      addMenuListenerToDragBarButton(b);
      addDragListenerToDragBarButton(b);//, 0);
      addLeftClickListenerToDragBarButton(b);
    }
  }

  private void setupToolTips()
  {
    yearTextField.setToolTipText("Enter the year of your data.");
    setYearButton.setToolTipText("Press to set the year for your data.");
    socialValueTargetTree.setToolTipText("Click on a node to set the target.");
    socialValueSourceTree.setToolTipText("Click on a node to set the source.");
    yAxisScaleInputText.setToolTipText("Enter the desired scale for the sliders.");
    yAxisScaleOKButton.setToolTipText("Press to set the scale specified above.");
    socialValueSaveButton.setToolTipText("Press and select the directory of where you want your save files.");
    socialValueLoadButton.setToolTipText("Press and select the directory of your save files.");
    socialValuesTabbedPane.setToolTipText("Use the sliders to specify grid/group.  Right click to define exceptions.");
    sortByChildrenButton.setToolTipText("Press to sort the buttons by children.");
    //socialValueNotesTextPane.setToolTipText("Don't take these tips seriously.");
    helpButton.setToolTipText("Press to see instructions, etc.");
    // set tips for all drag bar panels
    for (DragBarPanel dp : dragBarPanels)
    {
      dp.setToolTipText("Use the sliders to specify grid/group.  Right click to define exceptions.");
    }
  }

  // add listeners to the popup menu
  private void addPopupMouseListeners()
  {
    final DragBarPanel dbp = getCurrentPanel();

    // add listeners for refreshing
    MouseAdapter refresher = new MouseAdapter()
    {

      public void mouseClicked(java.awt.event.MouseEvent evt)
      {
        dbp.repaint();
      }

      public void mouseEntered(java.awt.event.MouseEvent evt)
      {
        // disable all other tabs to make it clear which the user is selecting
        for (int i = 0; i < socialValuesTabbedPane.getTabCount(); i++)
        {
          if (i != socialValuesTabbedPane.getSelectedIndex())
          {
            socialValuesTabbedPane.setEnabledAt(i, false);
          }
        }
        dbp.repaint();
      }

      public void mouseExited(java.awt.event.MouseEvent evt)
      {
        setAllTabsEnabled(true);
        dbp.repaint();
      }
    };
    expMenu.addMouseListenerToAll(refresher);

    ActionListener actionL = new ActionListener()
    {

      // THIS IS WHERE WE NEED TO FIX THE SINGLE DRAG BAR PANEL VS THE VECTOR!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      public void actionPerformed(java.awt.event.ActionEvent evt)
      {
        // re-enable tabs
        setAllTabsEnabled(true);
        // add listeners for selection
        DefaultMutableTreeNode selected = expMenu.getSelectedItem();
        // right now DOES NOT TAKE INTO ACCOUNT HIERARCHIES!!!!!!!!!!!!!!!!!!!!!!!!
        if (selected.isLeaf())
        {
          // check the selected to see what category it belongs to
          int categoryIndex = expMenu.getCategoryIndexOfNode(selected);
          // the parent and it's tracker are needed for proper disabling
          DefaultMutableTreeNode selectedParent = (DefaultMutableTreeNode) selected.getParent();

          Vector<DefaultMutableTreeNode> siblings = expMenu.getSiblings(selected);

          // create buttons or tabs for each sibling
          // if it's a button...
          if (rightClickedComponentInAltruismDialog.getClass().equals(DragBarButton.class))
          {
            // this will find the tracker for the pushed button
            /*
            SocialValueComponentTracker spawnTracker = null;
            for (int j = 0; j < buttonTrackers.get(socialValuesTabbedPane.getSelectedIndex()).size(); j++)
            {
            if (buttonTrackers.get(socialValuesTabbedPane.getSelectedIndex()).get(j).theComponent.equals(rightClickedComponentInAltruismDialog))
            {
            spawnTracker = buttonTrackers.get(socialValuesTabbedPane.getSelectedIndex()).get(j);
            }
            }
            spawnTracker.disabledAltruism.add((String) selectedParent.getUserObject());
            if (spawnTracker == null)
            System.out.println("THE SPAWN TRACKER IS NULL");

             */

            SocialValueComponentTracker spawnTracker = findTrackerForComponent(rightClickedComponentInAltruismDialog);
            DragBarPanel currentDragBarPanel = dragBarPanels.get(socialValuesTabbedPane.getSelectedIndex());
            for (int i = 0; i < siblings.size(); i++)
            {
              DefaultMutableTreeNode aSibling = siblings.get(i);
              DragBarButton newDBB = currentDragBarPanel.addNewButton((String) aSibling.getUserObject());
              addDoubleClickListenerToDragBarButton(newDBB);
              addMenuListenerToDragBarButton(newDBB);
              addLeftClickListenerToDragBarButton(newDBB);
              addDragListenerToDragBarButton(newDBB);
              currentDragBarPanel.repaint();

              // now we have the tracker, so we'll need the tracker's rep groups
              Vector<int[]> spawnRepGroups = spawnTracker.representedGroups;
              // this is the new rep groups for the new tracker
              Vector<int[]> newRepGroups = new Vector<int[]>();
              for (int j = 0; j < spawnRepGroups.size(); j++)
              {
                // copy only what DOES NOT contain a sibling name
                int[] candidate = spawnRepGroups.get(j);
                // string rep of candidate
                Vector<String> candidateString = currentAltruismMatrix.convertIndexIntoStringVector(candidate);

                // check the candidate at the category index
                boolean containsSibling = false;
                for (int k = 0; k < siblings.size(); k++)
                {
                  // this checks to see that we aren't comparing the same sibling to itself
                  if (k != i)
                  {
                    String siblingString = (String) siblings.get(k).getUserObject();
                    if (candidateString.get(categoryIndex).equals(siblingString))
                    {
                      containsSibling = true;
                    }
                  }
                }

                if (!containsSibling)
                {
                  newRepGroups.add(candidate);
                }
              }

              for (int k = 0; k < newRepGroups.size(); k++)
              {
                System.out.println("rep group: " + currentAltruismMatrix.convertIndexToString(newRepGroups.get(k)));
              }

              SocialValueComponentTracker tracker = new SocialValueComponentTracker(newDBB, ascriptiveCategories, newRepGroups);
              if (newDBB.getName() == null)
              {
                System.out.println("the name of newDBB is null!!!!!!!!!!!!!!!  LINE 1448");
              }
              tracker.disabledAltruism.add((String) selectedParent.getUserObject());
              // copy over parent button's disabled list too
              Vector<String> parentDisabledList = spawnTracker.getDisabledAltruism();
              for (int j = 0; j < parentDisabledList.size(); j++)
              {
                tracker.disabledAltruism.add(parentDisabledList.get(j));
              }
              // add the tracker to the button tracker vector
              buttonTrackers.get(socialValuesTabbedPane.getSelectedIndex()).add(tracker);

              // change the text to match new names
              String rightClickedName = (String) rightClickedComponentInAltruismDialog.getName();
              // this is the name of the newDBB BEFORE we add the additional information
              // about which button was clicked, etc.
              String newDBBName = newDBB.getName();
              String newName = rightClickedName;
              String newText = "<html>";
              // tokenize the old name to find breaks
              StringTokenizer tokenizer = new StringTokenizer(rightClickedName, ";");
              while (tokenizer.hasMoreTokens())
              {
                newText += tokenizer.nextToken() + "<br>";
              }
              newText += newDBBName + "</html>";
              newName += ";" + newDBBName;

              newDBB.setName(newName);
              newDBB.setText(newText);
            }

            // when we're done w/ the righclickedbutton, we set it to null b/c we don't want to
            // end up using it when it's not right clicked!
            rightClickedComponentInAltruismDialog = null;

            // resize the dragbarpanel
            // RIGHT NOW JUST AUTO INCREASES SIZE... NEED TO FIX
            // resize the container first
            // since we know that the container and panel are resizing, we know the scroll bars will appear
            // this will in turn cause difficulty reading the bottom row, so instead, we must decrease the
            // height of the container and panel by the height of the horizontal scroll bar.
            Dimension contD = dragBarContainer.getSize();
            Dimension newContD;

            // if the canvas scroll pane hasn't already created a bar, we need to subtract the height of the
            // bar... otherwise, we've already done it, so we don't do it again.
            if (canvasScrollPane.getHorizontalScrollBar().getSize().height == 0)
            {
              newContD = new Dimension((int) contD.getWidth() + 300, (int) contD.getHeight() - scrollBarH);
            }
            else
            {
              newContD = new Dimension((int) contD.getWidth() + 300, (int) contD.getHeight());
            }
            dragBarContainer.setSize(newContD);
            dragBarContainer.setPreferredSize(newContD);
            Dimension d = dragBarContainer.getSize();
            currentDragBarPanel.setPreferredSize(d);
            currentDragBarPanel.setSize(d);

            // sort the buttons so the children are near the parents
            System.out.println("the number of buttons is: " + currentDragBarPanel.getButtons().size());
            sortButtonsByChildren();
            // disable buttons that don't have populations
            //setEnabledAllAltruismButtons(true);
            //setEnabledAllZeroPopulationAltruismButtons(false);
            int selectedIndex = socialValuesTabbedPane.getSelectedIndex();
            setButtonsOnDragBarPanel(selectedIndex);
            currentDragBarPanel.repaint();
          }
          else // must be a tab
          {
            settingUpNewTabs = true;
            // first we enable all the tabs again b/c they were disabled from right clicking
            setAllTabsEnabled(true);
            // this tells us which tab was right clicked
            int parentIndex = socialValuesTabbedPane.getSelectedIndex();

            // since we know it's a tab, we need to first need to find out which tab it is
            // then we create sibling tabs for each sibling
            // FOR NOW: THE TAB IS ALWAYS THE SELECTED TAB!!!!!!!!!!!!!!!!!!!!!!
            SocialValueComponentTracker selectedTabTracker = tabTrackers.get(socialValuesTabbedPane.getSelectedIndex());

            // we have the siblings, so lets make tabs
            for (int i = 0; i < siblings.size(); i++)
            {
              DefaultMutableTreeNode aSibling = siblings.get(i);

              // find the represented groups for this tab
              // now we have the tracker, so we'll need the tracker's rep groups
              Vector<int[]> spawnRepGroups = selectedTabTracker.representedGroups;
              // this is the new rep groups for the new tracker
              Vector<int[]> newRepGroups = new Vector<int[]>();
              for (int j = 0; j < spawnRepGroups.size(); j++)
              {
                // copy only what DOES NOT contain a sibling name
                int[] candidate = spawnRepGroups.get(j);
                // string rep of candidate
                Vector<String> candidateString = currentAltruismMatrix.convertIndexIntoStringVector(candidate);

                // check the candidate at the category index
                boolean containsSibling = false;
                for (int k = 0; k < siblings.size(); k++)
                {
                  // this checks to see that we aren't comparing the same sibling to itself
                  if (k != i)
                  {
                    String siblingString = (String) siblings.get(k).getUserObject();
                    if (candidateString.get(categoryIndex).equals(siblingString))
                    {
                      containsSibling = true;
                    }
                  }
                }

                if (!containsSibling)
                {
                  newRepGroups.add(candidate);
                }
              }

              System.out.println("DRAG BAR PANEL IS GIVEN A TRACKER");
              // create a new dragbarpanel to hold the sibling buttons
              DragBarPanel currentPanel = dragBarPanels.get(socialValuesTabbedPane.getSelectedIndex());
              DragBarPanel newDragBarPanel = new DragBarPanel(currentPanel.getButtonCount());
              setupToolTips();
              dragBarPanels.add(newDragBarPanel);
              newDragBarPanel.setSize(currentPanel.getSize());
              newDragBarPanel.setPreferredSize(currentPanel.getSize());
              //SocialValueComponentTracker tracker = new SocialValueComponentTracker(theDragBarPanel, ascriptiveCategories, newRepGroups);
              SocialValueComponentTracker tracker = new SocialValueComponentTracker(newDragBarPanel, ascriptiveCategories, newRepGroups);
              tracker.disabledAltruism.add((String) selectedParent.getUserObject());
              // copy over parent components's disabled list too
              Vector<String> parentDisabledList = selectedTabTracker.getDisabledAltruism();
              for (int j = 0; j < parentDisabledList.size(); j++)
              {
                tracker.disabledAltruism.add(parentDisabledList.get(j));
              }

              tabTrackers.add(tracker);

              // change the text to match new names
              String tabName = socialValuesTabbedPane.getTitleAt(socialValuesTabbedPane.getSelectedIndex());
              tabName += ", " + (String) aSibling.getUserObject();

              // the container for the drag bar button
              JPanel dbpContainer = new JPanel();
              //dbpContainer.setLayout(new GroupLayout(dbpContainer));
              dbpContainer.setLayout(null);
              dbpContainer.updateUI();
              dbpContainer.setBackground(Color.white);
              dbpContainer.setSize(currentPanel.getSize());
              dbpContainer.setPreferredSize(currentPanel.getSize());
              dbpContainer.add(newDragBarPanel);

              // TODO add your handling code here:
              // create a panel for this new tab
              JPanel newTabPanel = new JPanel();
              //newTabPanel.setLayout(new GroupLayout(newTabPanel));
              newTabPanel.setLayout(null);
              newTabPanel.updateUI();
              newTabPanel.setBackground(Color.white);
              newTabPanel.setSize(DEFAULT_DRAG_BAR_CONTAINER_SIZE);
              newTabPanel.setPreferredSize(DEFAULT_DRAG_BAR_CONTAINER_SIZE);

              // scroll pane for the new tab
              JScrollPane sp = new JScrollPane(dbpContainer);
              System.out.println(dbpContainer.getSize());
              //sp.setLayout(new GroupLayout(sp));
              sp.updateUI();
              sp.setBackground(Color.white);
              // some small size difference to account for size of bars themselves
              Dimension scrollPanelSize = new Dimension(DEFAULT_DRAG_BAR_CONTAINER_SIZE.width, DEFAULT_DRAG_BAR_CONTAINER_SIZE.height - 10);
              sp.setSize(scrollPanelSize);
              sp.setPreferredSize(scrollPanelSize);
              sp.setAutoscrolls(true);
              newTabPanel.add(sp);

              /*
              // the container for the drag bar button
              JPanel dbpContainer = new JPanel();
              dbpContainer.setLayout(null);
              dbpContainer.updateUI();
              dbpContainer.setBackground(Color.white);
              dbpContainer.setSize(currentPanel.getSize());
              dbpContainer.setPreferredSize(currentPanel.getSize());
              dbpContainer.add(newDragBarPanel);

              // create a panel for this new tab
              JPanel newTabPanel = new JPanel();
              newTabPanel.setLayout(null);
              newTabPanel.updateUI();
              newTabPanel.setBackground(Color.white);
              newTabPanel.setSize(currentPanel.getSize());
              newTabPanel.setPreferredSize(currentPanel.getSize());
              // scroll pane for the new tab
              JScrollPane sp = new JScrollPane(dbpContainer);
              sp.setLayout(null);
              sp.updateUI();
              sp.setBackground(Color.white);
              sp.setSize(DEFAULT_DRAG_BAR_CONTAINER_SIZE);
              sp.setPreferredSize(DEFAULT_DRAG_BAR_CONTAINER_SIZE);
              sp.setAutoscrolls(true);
              newTabPanel.add(sp);

              //sp.setViewportView(dbpContainer);
              //sp.add(dbpContainer);
               */
              // now that the tracker is setup and we have the panel, add a new tab
              socialValuesTabbedPane.addTab(tabName, newTabPanel);

              // lastly, b/c this is a new tab, there needs to be a new vector of altruism button trackers
              Vector<SocialValueComponentTracker> newButtonTrackers = new Vector<SocialValueComponentTracker>();
              Vector<SocialValueComponentTracker> oldButtonTrackers = buttonTrackers.get(parentIndex);
              System.out.println("oldbutton size: " + oldButtonTrackers.size());

              // copy over the old tracker b/c we want each new sibling pane to have the same sources
              for (int m = 0; m < oldButtonTrackers.size(); m++)
              {
                SocialValueComponentTracker oldB = oldButtonTrackers.get(m);
                // THIS COMPONENT IS WRONG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                Component newtheComponent = oldB.theComponent;
                Vector<String> newascriptiveCategories = (Vector<String>) oldB.ascriptiveCategories.clone();
                Vector<String> newcomponentAscriptives = (Vector<String>) oldB.componentAscriptives.clone();
                Vector<int[]> newrepresentedGroups = (Vector<int[]>) oldB.representedGroups.clone();
                Vector<String> newDisabledList = (Vector<String>) oldB.disabledAltruism.clone();

                SocialValueComponentTracker newTracker = new SocialValueComponentTracker(newtheComponent, newascriptiveCategories, newcomponentAscriptives, newrepresentedGroups);
                newTracker.disabledAltruism = newDisabledList;
                newButtonTrackers.add(newTracker);
              }
              System.out.println("newButtonSize: " + newButtonTrackers.size());

              // now that the buttons have trackers, make sure that they also have listeners
              Vector<DragBarButton> newDBPButtons = newDragBarPanel.getButtons();
              for (int m = 0; m < newDBPButtons.size(); m++)
              {
                DragBarButton dbb = newDBPButtons.get(m);
                addDoubleClickListenerToDragBarButton(dbb);
                addMenuListenerToDragBarButton(dbb);
                addLeftClickListenerToDragBarButton(dbb);
                addDragListenerToDragBarButton(dbb);
                // also have to fix the component for the tracker
                newButtonTrackers.get(m).theComponent = dbb;
              }

              // add the new Buttons to the tracker vector
              buttonTrackers.add(newButtonTrackers);
              int newIndex = buttonTrackers.indexOf(newButtonTrackers);
              System.out.println("index of new buttons: " + newIndex);
              System.out.println("altruismTrackers size: " + buttonTrackers.get(i).size());
            }

            // when we're done w/ the righclickedbutton, we set it to null b/c we don't want to
            // end up using it when it's not right clicked!
            rightClickedComponentInAltruismDialog = null;
            settingUpNewTabs = false;
          }
        }
      }
    };
    expMenu.addActionListenerToAll(actionL);
  }

  public void addLeftClickListenerToDragBarButton(final DragBarButton db)
  {
    db.addActionListener(new java.awt.event.ActionListener()
    {

      public void actionPerformed(java.awt.event.ActionEvent evt)
      {
        SocialValueComponentTracker bTracker = findTrackerForComponent(db);
        Vector<int[]> repGroups = bTracker.representedGroups;
        for (int[] g : repGroups)
        {
          Vector<String> stringRep = currentAltruismMatrix.convertIndexIntoStringVector(g);
          String p = "";
          for (String s : stringRep)
          {
            p += s + " * ";
          }
          System.out.println(p + "\n");
        }
      }
    });
  }

  // for double clicking... displays group details for tweaking, etc
  public void addDoubleClickListenerToDragBarButton(final DragBarButton db)
  {
    db.addMouseListener(new java.awt.event.MouseAdapter()
    {

      public void mouseClicked(java.awt.event.MouseEvent evt)
      {
        if (evt.getClickCount() >= 2)
        {
          groupDetailsDialog.setVisible(true);
          SocialValueComponentTracker tracker = findTrackerForComponent(db);
          Vector<int[]> repGroups = tracker.representedGroups;

          // change the group details labels
          gDP.getGroupDetailsTitlePane().setText(db.getText());

          // set the repreented groups
          gDP.representedGroups = repGroups;

          gDP.getGroupDetailsPopulationTextPane().setText("" + findPopulationForComponent(db, currentYear));
        }
      }
    });
  }

  // adds a poopup menu listener to a button
  public void addMenuListenerToDragBarButton(final DragBarButton db)
  {
    db.addMouseListener(new java.awt.event.MouseAdapter()
    {

      public void mouseReleased(java.awt.event.MouseEvent evt)
      {
        setButtonsOnDragBarPanel(socialValuesTabbedPane.getSelectedIndex());
      }

      public void mouseClicked(java.awt.event.MouseEvent evt)
      {
        System.out.println("population of this button: " + findPopulationForComponent(db, currentYear));

        if (SwingUtilities.isRightMouseButton(evt))
        {
          // enable all options first, then disable the proper ones
          expMenu.enableAll();

          // disable the proper menu options
          /*
           * To find what to disable, we'll need the button tracker associated
           * w/ this button.  Then we use the represented groups to find which
           * category(or categories) is not fully represented.  If they are not
           * fully represented, then there must exist another button on the
           * panel that represents the missing pieces.  This in turn tells us
           * to disable the category b/c we don't want overlapping buttons.
           */
          SocialValueComponentTracker bTracker = null;
          for (int i = 0; i < buttonTrackers.get(socialValuesTabbedPane.getSelectedIndex()).size(); i++)
          {
            SocialValueComponentTracker current = buttonTrackers.get(socialValuesTabbedPane.getSelectedIndex()).get(i);

            if (current.theComponent.equals(db))
            {
              bTracker = current;
            }
          }

          Vector<String> disabledList = bTracker.disabledAltruism;
          for (int i = 0; i < disabledList.size(); i++)
          {
            expMenu.disableEntry(disabledList.get(i));
          }

          expMenu.show(evt.getComponent(), evt.getX(), evt.getY());
          rightClickedComponentInAltruismDialog = db;
          dragBarPanels.get(socialValuesTabbedPane.getSelectedIndex()).repaint();
        }
      }
    });
  }

  public void addDragListenerToDragBarButton(final DragBarButton b)//, int dragBarPanelIndex)
  {
    b.addMouseMotionListener(new java.awt.event.MouseMotionAdapter()
    {

      public void mouseDragged(java.awt.event.MouseEvent evt)
      {
        // setup changes to the notes pane
        double value = b.getValue();
        if (value < 0)
        {
          if (value < -.8)
          {
            socialValueNotesTextPane.setText(negativeAltruismAnnouncements[4]);
          }
          else
          {
            if (value < -.6)
            {
              socialValueNotesTextPane.setText(negativeAltruismAnnouncements[3]);
            }
            else
            {
              if (value < -.4)
              {
                socialValueNotesTextPane.setText(negativeAltruismAnnouncements[2]);
              }
              else
              {
                if (value < -.2)
                {
                  socialValueNotesTextPane.setText(negativeAltruismAnnouncements[1]);
                }
                else
                {
                  if (value < 0)
                  {
                    socialValueNotesTextPane.setText(negativeAltruismAnnouncements[0]);
                  }
                }
              }
            }
          }
        }
        else
        {
          if (value == 0)
          {
            socialValueNotesTextPane.setText(neutralAltruismAnnouncement);
          }
          else // else it's negative
          {
            if (value > .8)
            {
              socialValueNotesTextPane.setText(positiveAltruismAnnouncements[4]);
            }
            else
            {
              if (value > .6)
              {
                socialValueNotesTextPane.setText(positiveAltruismAnnouncements[3]);
              }
              else
              {
                if (value > .4)
                {
                  socialValueNotesTextPane.setText(positiveAltruismAnnouncements[2]);
                }
                else
                {
                  if (value > .2)
                  {
                    socialValueNotesTextPane.setText(positiveAltruismAnnouncements[1]);
                  }
                  else
                  {
                    if (value > 0)
                    {
                      socialValueNotesTextPane.setText(positiveAltruismAnnouncements[0]);
                    }
                  }
                }
              }
            }
          }
        }

        // setup changes to the altruism matrix
        // need to find the tracker first.
        SocialValueComponentTracker bTracker = null;
        // THIS PART IS MESSED UP B/C TECHINICALLY THE BUTTONS CAN BE ON DIFFERENT DRAG BAR PANELS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        int buttonIndex = -1;
        for (DragBarPanel dbp : dragBarPanels)
        {
          Vector<DragBarButton> theDBButtons = dbp.getButtons();//theDragBarPanel.getButtons();
          for (int i = 0; i < theDBButtons.size(); i++)
          {
            if (theDBButtons.get(i).equals(b))
            {
              buttonIndex = i;
            }
          }
        }
        bTracker = buttonTrackers.get(socialValuesTabbedPane.getSelectedIndex()).get(buttonIndex);

        // there better be a tracker here!!!!!
        Vector<int[]> representedSourceGroups = bTracker.representedGroups;
        // NEED TO FIX THIS SO IT HANDLES TABBING LATER
        Vector<int[]> representedTargetGroups = tabTrackers.get(socialValuesTabbedPane.getSelectedIndex()).representedGroups;
        // ALTRUISM MATRIX HAD BETTER ALREADY BE SET THE FUCK UP!
        // for now, we don't take into account population, however we'll need to do that later
        // for now, we'll just set everything to the value, since then it'll average out to
        // what the button is at
        for (int i = 0; i < representedSourceGroups.size(); i++)
        {
          int[] sourceGroup = representedSourceGroups.get(i);

          // TEST PRINTING
          for (int m = 0; m < sourceGroup.length; m++)
          {
            if (sourceGroup[m] == -1)
            {
              System.out.println("found -1 at source group: " + m);
            }
          }

          for (int j = 0; j < representedTargetGroups.size(); j++)
          {
            int[] targetGroup = representedTargetGroups.get(j);

            // TEST PRINTING
            for (int n = 0; n < targetGroup.length; n++)
            {
              if (targetGroup[n] == -1)
              {
                System.out.println("found -1 at target group: " + n);
              }
            }

            // set the altruism matrix here
            double newValue = b.getValueDifference() + currentAltruismMatrix.getSocialValue(sourceGroup, targetGroup);
            currentAltruismMatrix.setAltruism(sourceGroup, targetGroup, newValue);
          }
        }

        // now that the altruism is set, move buttons to the correct positions
        DragBarPanel currentPanel = getCurrentPanel();
        Vector<DragBarButton> theButtons = currentPanel.getButtons();
        for (int i = 0; i < theButtons.size(); i++)
        {
          DragBarButton aButton = theButtons.get(i);

          // do not move the button that's already moving
          if (!aButton.equals(b))
          {
            SocialValueComponentTracker aButtonTracker = findTrackerForComponent(aButton);
            if (aButtonTracker == null)
            {
              System.out.println("TRACKER IS NULL!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
            }
            Vector<int[]> buttonSources = aButtonTracker.representedGroups;
            Vector<int[]> targets = tabTrackers.get(socialValuesTabbedPane.getSelectedIndex()).representedGroups;

            MultiArray<Integer> yearCount = populationCounts.get(currentYear);
            double aButtonValue = currentAltruismMatrix.getAverageAltruismMultipleSourcesAndTargetsWithPopulation(buttonSources, targets, yearCount);
            // comment in the below and comment out the above to use no population testing
            //double aButtonValue = altruismMatrix.getAverageAltruismMultipleSourcesAndTargets(buttonSources, targets);
            /*if (i == 0)
            {
            double special = altruismMatrix.special(buttonSources, targets, populationCounts);
            System.out.println("abutton value: " + special);
            }*/
            currentPanel.setButtonValueAndMove(aButton, aButtonValue);
          }
        }
      }
    });
  }

  // adds a popup listener to a tab in the tabbed pane
  // DO NOT PASS ANYTHING BUT A TAB INTO THIS METHOD
  private void addRightClickPopupMenuListenerToTabbedPane()
  {
    if (socialValuesTabbedPane != null)
    {
      socialValuesTabbedPane.addMouseListener(new java.awt.event.MouseAdapter()
      {

        public void mouseClicked(java.awt.event.MouseEvent evt)
        {
          if (SwingUtilities.isRightMouseButton(evt))
          {
            // enable all options first, then disable the proper ones
            expMenu.enableAll();

            // disable the proper menu options
            /*
             * To find what to disable, we'll need the button tracker associated
             * w/ this button.  Then we use the represented groups to find which
             * category(or categories) is not fully represented.  If they are not
             * fully represented, then there must exist another button on the
             * panel that represents the missing pieces.  This in turn tells us
             * to disable the category b/c we don't want overlapping buttons.
             */
            int tabIndex = socialValuesTabbedPane.getSelectedIndex();
            SocialValueComponentTracker tabTracker = tabTrackers.get(tabIndex);

            Vector<String> disabledList = tabTracker.disabledAltruism;
            for (int i = 0; i < disabledList.size(); i++)
            {
              expMenu.disableEntry(disabledList.get(i));
            }

            expMenu.show(evt.getComponent(), evt.getX(), evt.getY());
            rightClickedComponentInAltruismDialog = socialValuesTabbedPane;

            DragBarPanel currentPanel = getCurrentPanel();
            currentPanel.repaint();
          }
        }
      });
    }
    else
    {
      System.out.println("tab is null");
    }
  }

  // sets up the horizontal and vertical scroll bars for the scroll pane
  // that contains the altruism panel... this is used to refresh when the user
  // creates new buttons
  public void setupAltruismScrollBarListeners()
  {
    JComponent horizontalScrollBar = canvasScrollPane.getHorizontalScrollBar();
    JComponent verticalScrollBar = canvasScrollPane.getVerticalScrollBar();

    horizontalScrollBar.addMouseListener(new java.awt.event.MouseAdapter()
    {

      public void mousePressed(java.awt.event.MouseEvent evt)
      {
        getCurrentPanel().repaint();
      }

      public void mouseExited(java.awt.event.MouseEvent evt)
      {
        getCurrentPanel().repaint();
      }

      public void mouseReleased(java.awt.event.MouseEvent evt)
      {
        getCurrentPanel().repaint();
      }
    });

    horizontalScrollBar.addMouseMotionListener(new java.awt.event.MouseMotionAdapter()
    {

      public void mouseDragged(java.awt.event.MouseEvent evt)
      {
        getCurrentPanel().repaint();
      }
    });

    // vertical bar
    verticalScrollBar.addMouseListener(new java.awt.event.MouseAdapter()
    {

      public void mousePressed(java.awt.event.MouseEvent evt)
      {
        getCurrentPanel().repaint();
      }

      public void mouseExited(java.awt.event.MouseEvent evt)
      {
        getCurrentPanel().repaint();
      }

      public void mouseReleased(java.awt.event.MouseEvent evt)
      {
        getCurrentPanel().repaint();
      }
    });

    verticalScrollBar.addMouseMotionListener(new java.awt.event.MouseMotionAdapter()
    {

      public void mouseDragged(java.awt.event.MouseEvent evt)
      {
        getCurrentPanel().repaint();
      }
    });
  }

  // sets all altruism buttons to the intput boolean
  private void setEnabledAllAltruismButtons(boolean bool)
  {
    Vector<DragBarButton> theAltButtons = getCurrentPanel().getButtons();

    for (int i = 0; i < theAltButtons.size(); i++)
    {
      theAltButtons.get(i).setEnabled(bool);
    }
  }

  // sets all the buttons that represent groups w/ no population to the input boolean
  private void setEnabledAllZeroPopulationAltruismButtons(boolean bool)
  {
    Vector<DragBarButton> theButtons = getCurrentPanel().getButtons();

    for (int i = 0; i < theButtons.size(); i++)
    {
      DragBarButton b = theButtons.get(i);
      SocialValueComponentTracker t = findTrackerForComponent(b);
      Vector<int[]> representedGroups = t.representedGroups;
      int totalPopulation = 0;

      for (int j = 0; j < representedGroups.size(); j++)
      {
        int[] currentGroup = representedGroups.get(j);
        totalPopulation += populationCounts.get(currentYear).getElementAtIndex(currentGroup);
      }

      if (totalPopulation <= 0)
      {
        b.setEnabled(bool);
      }
    }
  }

  private void setAllTabsEnabled(boolean bool)
  {
    for (int i = 0; i < socialValuesTabbedPane.getTabCount(); i++)
    {
      socialValuesTabbedPane.setEnabledAt(i, bool);
    }
  }

  // sets all visible flags
  private void setVisibleAllAltruismButtons(boolean bool)
  {
    Vector<DragBarButton> theAltButtons = getCurrentPanel().getButtons();

    for (int i = 0; i < theAltButtons.size(); i++)
    {
      theAltButtons.get(i).setVisible(bool);
      theAltButtons.get(i).getTheLabel().setVisible(bool);
    }
  }

  // requires that the trackers be already set
  private void moveButtonsBasedOnAltruism(DragBarPanel dbPanel, Vector<SocialValueComponentTracker> buttonTrackers,
          SocialValueComponentTracker targetTracker)
  {
    Vector<DragBarButton> theButtons = dbPanel.getButtons();

    for (int i = 0; i < theButtons.size(); i++)
    {
      DragBarButton b = theButtons.get(i);
      SocialValueComponentTracker buttonT = buttonTrackers.get(i);

      Vector<int[]> sources = buttonT.representedGroups;
      Vector<int[]> targets = targetTracker.representedGroups;
      MultiArray<Integer> yearCount = populationCounts.get(currentYear);
      if (yearCount == null)
      {
        System.out.println("NULLLLLLL!!!!");
      }
      double average = currentAltruismMatrix.getAverageAltruismMultipleSourcesAndTargetsWithPopulation(sources, targets, yearCount);
      //double average = 0.2;// testing!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      //altruismMatrix.getAverageAltruismMultipleSourcesAndTargets(sources, targets);
      dbPanel.setButtonValueAndMove(b, average);
    }
  }

  private SocialValueComponentTracker findTrackerForComponent(Component c)
  {
    SocialValueComponentTracker ret = null;

    // if it's a button
    if (c instanceof DragBarButton)
    {
      for (Vector<SocialValueComponentTracker> currentButtonVector : buttonTrackers)
      {
        for (SocialValueComponentTracker aTracker : currentButtonVector)
        {
          if (c.equals(aTracker.theComponent))
          {
            ret = aTracker;
          }
        }
      }
    }
    else  // else it's a tab
    {
      for (SocialValueComponentTracker tabTracker : tabTrackers)
      {
        if (c.equals(tabTracker.theComponent))
        {
          ret = tabTracker;
        }
      }
    }
    return ret;
  }

  public void setPopulationCountAt(int[] index, int newValue, int year)
  {
    populationCounts.get(year).setElementAtIndex(index, newValue);
  }

  public void setAllPopulationTo(int newValue)
  {
    // this uses the altruism matrix combinations, but that's okay b/c they'll have
    // the same dimentions

    Vector<int[]> allCombos = currentAltruismMatrix.getAllCombinations();
    for (int i = 0; i < allCombos.size(); i++)
    {
      setPopulationCountAt(allCombos.get(i), newValue, currentYear);
    }
  }

  // ONLY USE THIS W/ POPULATION OF DEFAULT TREES (FOOD, COLOR, SPORTS TREE)
  private void setupTestPopulation()
  {
    setAllPopulationTo(0);

    // create exceptions that have zero population
    int[] zeroPop0 =
    {
      0, 0, 0
    };
    int[] zeroPop1 =
    {
      1, 0, 0
    };
    int[] zeroPop2 =
    {
      2, 0, 0
    };
    int[] zeroPop3 =
    {
      3, 0, 0
    };

    setPopulationCountAt(zeroPop0, 0, currentYear);
    setPopulationCountAt(zeroPop1, 0, currentYear);
    setPopulationCountAt(zeroPop2, 0, currentYear);
    setPopulationCountAt(zeroPop3, 0, currentYear);

    // create children that have varying population
    int[] varyPop0 =
    {
      0, 1, 0
    };
    int[] varyPop1 =
    {
      0, 2, 0
    };
    int[] varyPop2 =
    {
      0, 3, 0
    };

    setPopulationCountAt(varyPop0, 200, currentYear);
    setPopulationCountAt(varyPop1, 5, currentYear);
    setPopulationCountAt(varyPop2, 100, currentYear);
  }

  private int findPopulationForComponent(Component c, int year)
  {
    SocialValueComponentTracker aTracker = findTrackerForComponent(c);

    int sum = 0;
    Vector<int[]> representedGroups = aTracker.representedGroups;
    for (int i = 0; i < representedGroups.size(); i++)
    {
      sum += populationCounts.get(year).getElementAtIndex(representedGroups.get(i));
    }

    return sum;
  }

  // returns true if the child is a child of the parent.
  private boolean isChild(SocialValueComponentTracker child, SocialValueComponentTracker parent)
  {
    Vector<int[]> childRepGroups = child.representedGroups;
    Vector<int[]> parentRepGroups = parent.representedGroups;

    // return false if the child rep groups is too large for the parent to contain it
    if (childRepGroups.size() > parentRepGroups.size())
    {
      return false;
    }

    // loop through the child to see if each group is in the parent
    for (int i = 0; i < childRepGroups.size(); i++)
    {
      int[] childGroup = childRepGroups.get(i);

      // look for child in the parent
      boolean match = false;
      for (int j = 0; j < parentRepGroups.size(); j++)
      {
        int[] parentGroup = parentRepGroups.get(j);

        if (parentGroup.length != childGroup.length)
        {
          System.out.println("SIZE ERROR FOUND IN ISCHILD METHOD!");
          return false;
        }

        boolean currentComparison = true;
        for (int k = 0; k < childGroup.length; k++)
        {
          if (childGroup[k] != parentGroup[k])
          {
            currentComparison = false;
          }
        }
        if (currentComparison)
        {
          match = true;
        }
      }

      // if there's no match for this child group, then the child cannot be a subset
      // of the parent
      if (!match)
      {
        return false;
      }
    }

    // if you got here, then the contents must match
    return true;
  }

  public void nullTrackersExist()
  {
    boolean nullExists = false;
    for (DragBarPanel dBP : dragBarPanels)
    {
      for (DragBarButton dbb : dBP.getButtons())
      {
        SocialValueComponentTracker cT = this.findTrackerForComponent(dbb);
        if (cT == null)
        {
          nullExists = true;
        }
      }
    }

    if (nullExists)
    {
      System.out.println("NULL TRACKER EXISTS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
    }
    else
    {
      System.out.println("EVERYTHING IS OK!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
    }
  }

  private void setupIndexMapsForTranslation()
  {
    if (rt != null)
    {
      // first we need the category indices in robert's rt
      HashMap<String, Integer> robertsCategoryIndices = new HashMap<String, Integer>();
      Vector<String> categoryNames = currentAltruismMatrix.getAscriptiveCategories();
      for (String s : categoryNames)
      {
        robertsCategoryIndices.put(s, rt.getAscriptiveIndex(s));
      }

      // now let's map all my indices to robert's
      rToEIndexMap = new HashMap<int[], int[]>();
      eToRIndexMap = new HashMap<int[], int[]>();
      Vector<int[]> allCombos = currentAltruismMatrix.getAllCombinations();
      for (int[] c : allCombos)
      {
        int[] rtIndex = new int[c.length];
        Vector<String> cStringVector = currentAltruismMatrix.convertIndexIntoStringVector(c);

        for (int i = 0; i < c.length; i++)
        {
          String currentString = cStringVector.get(i);
          String category = categoryNames.get(i);
          int catIndex = robertsCategoryIndices.get(category);

          rtIndex[catIndex] = rt.getAscriptiveIndex(catIndex, currentString);
        }

        eToRIndexMap.put(c, rtIndex);
        rToEIndexMap.put(rtIndex, c);
      }

      // time to check the maps
      for (int[] c : allCombos)
      {
        int[] r = eToRIndexMap.get(c);
        int[] rprime = rToEIndexMap.get(r);
        String p = "";
        boolean error = false;
        for (int i = 0; i < c.length; i++)
        {
          int ci = c[i];
          int rprimei = rprime[i];
          p += "ci: " + ci + " p: " + rprimei + ", ";
          if (ci != rprimei)
          {
            System.out.println("MISMATCH!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
            error = true;
          }
        }
        if (error)
        {
          System.out.println("error is: " + p);
        }
      }

    /*
    int[] t = {0, 0};
    int[] r = rToEIndexMap.get(t);
    String p = "";
    for (int i = 0; i < t.length; i++)
    {
    p+= r[i] + ", ";
    }
    System.out.println("ROBERTS: " + p);
     */

    // testing stuff
      /*
    int[] aCombo = allCombos.get(randGen.nextInt(allCombos.size()));
    Vector<String> aComboV = currentAltruismMatrix.convertIndexIntoStringVector(aCombo);
    int[] robertsTestIndex = indexMap.get(aCombo);
    String p = "";
    for (int i = 0; i < aCombo.length; i++)
    {
    p += aComboV.get(i) + ", ";
    }
    System.out.println("MY STRING");
    System.out.println(p);

    String[] robertsTestString = rt.getAscriptiveNames(robertsTestIndex);
    String r = "";
    for (int i = 0; i < robertsTestString.length; i++)
    {
    r += robertsTestString[i] + ", ";
    }
    System.out.println("ROBERTS STRING");
    System.out.println(r);

    String t = "";
    for (int i = 0; i < aCombo.length; i++)
    {
    t += "[" + aCombo[i] + ", " + robertsTestIndex[i] + "] *";
    }
    System.out.println(t);
     * */
    }
    else
    {
      System.out.println("dude, i never got translated!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
    }
  }

  private DragBarPanel getCurrentPanel()
  {
    return dragBarPanels.get(socialValuesTabbedPane.getSelectedIndex());
  }

  public HashMap<Integer, SocialMatrix> getAltruismMatrices()
  {
    return altruismMatrices;
  }

  public SocialMatrix getCurrentMatrix()
  {
    return altruismMatrices.get(currentYear);
  }

  public MultiArray<Integer> getCurrentPopulation()
  {
    return populationCounts.get(currentYear);
  }

    private void dragBarContainerMouseEntered(java.awt.event.MouseEvent evt)//GEN-FIRST:event_dragBarContainerMouseEntered
    {//GEN-HEADEREND:event_dragBarContainerMouseEntered
      System.out.println("this is the container size: " + dragBarContainer.getSize().toString());
}//GEN-LAST:event_dragBarContainerMouseEntered

    private void dragBarContainerMouseExited(java.awt.event.MouseEvent evt)//GEN-FIRST:event_dragBarContainerMouseExited
    {//GEN-HEADEREND:event_dragBarContainerMouseExited
}//GEN-LAST:event_dragBarContainerMouseExited

    private void canvasScrollPaneMouseEntered(java.awt.event.MouseEvent evt)//GEN-FIRST:event_canvasScrollPaneMouseEntered
    {//GEN-HEADEREND:event_canvasScrollPaneMouseEntered
      // TODO add your handling code here:
      System.out.println("scroll pane entered!");
}//GEN-LAST:event_canvasScrollPaneMouseEntered

    private void canvasScrollPaneMouseDragged(java.awt.event.MouseEvent evt)//GEN-FIRST:event_canvasScrollPaneMouseDragged
    {//GEN-HEADEREND:event_canvasScrollPaneMouseDragged
      // TODO add your handling code here:
      System.out.println("scroll pane dragging!");
}//GEN-LAST:event_canvasScrollPaneMouseDragged

    private void socialValuesTabbedPaneStateChanged(javax.swing.event.ChangeEvent evt)//GEN-FIRST:event_socialValuesTabbedPaneStateChanged
    {//GEN-HEADEREND:event_socialValuesTabbedPaneStateChanged
      /*
      if (firstTrackersSetup && !settingUpNewTabs)
      {
      // if any state changed in this tabbed pane, make sure that the buttons are what should
      // be displayed AND that the panel is displayed on the selected tab
      JPanel selectedPanel = (JPanel) socialValuesTabbedPane.getSelectedComponent();
      //selectedPanel.setLayout(null);

      selectedPanel.add(movingPanel);
      movingPanel.setLocation(new Point(0, 0));
      movingPanel.setSize(selectedPanel.getSize());
      movingPanel.setPreferredSize(selectedPanel.getPreferredSize());
      System.out.println("name of parent: " + movingPanel.getParent().getName());
      selectedPanel.updateUI();
      selectedPanel.repaint();
      movingPanel.updateUI();
      setButtonsOnDragBarPanel();

      System.out.println("look the tab was pressed");
      }*/
      // don't place buttons unless they've activated the dragbarpanel
      if (socialValuesSourcesSetup && socialValuesTargetsSetup && yearSet)
      {
        setButtonsOnDragBarPanel(socialValuesTabbedPane.getSelectedIndex());
        DragBarPanel currentPanel = getCurrentPanel();
        double panelScale = currentPanel.getScale();
        // set text based on current scale
        yAxisScaleInputText.setText("" + panelScale);

        int index = socialValuesTabbedPane.getSelectedIndex();
        SocialValueComponentTracker panelTracker = tabTrackers.get(index);
        Vector<int[]> repGroups = panelTracker.representedGroups;
        String p = "";
        for (int[] array : repGroups)
        {
          Vector<String> stringRep = currentAltruismMatrix.convertIndexIntoStringVector(array);
          for (String s : stringRep)
          {
            p += s + " ";
          }
        }
      //System.out.println(p + "\n");
      }
}//GEN-LAST:event_socialValuesTabbedPaneStateChanged

    private void yAxisScaleInputTextMouseEntered(java.awt.event.MouseEvent evt)//GEN-FIRST:event_yAxisScaleInputTextMouseEntered
    {//GEN-HEADEREND:event_yAxisScaleInputTextMouseEntered
      // TODO add your handling code here:
      yAxisScaleInputText.setText("" + getCurrentPanel().getScale());
}//GEN-LAST:event_yAxisScaleInputTextMouseEntered

    private void yAxisScaleOKButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_yAxisScaleOKButtonActionPerformed
    {//GEN-HEADEREND:event_yAxisScaleOKButtonActionPerformed
      // TODO add your handling code here:
      getCurrentPanel().setScale(Double.parseDouble(yAxisScaleInputText.getText()));
      setButtonsOnDragBarPanel(socialValuesTabbedPane.getSelectedIndex());
}//GEN-LAST:event_yAxisScaleOKButtonActionPerformed

    private void socialValueSaveButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_socialValueSaveButtonActionPerformed
    {//GEN-HEADEREND:event_socialValueSaveButtonActionPerformed
      //System.out.println("printing all of the matrix:");
      //altruismMatrix.printAll();
      //System.out.println("DONE W/ PRINTING THE MATRIX");
      try
      {
        fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        int saveVal = fileChooser.showSaveDialog(this);
        if (saveVal == JFileChooser.APPROVE_OPTION)
        {
          File socialValueSaveFileDirectory = fileChooser.getSelectedFile();
          String directoryName = socialValueSaveFileDirectory.getAbsolutePath();

          // save all values from altruism matrices
          Set years = altruismMatrices.keySet();
          Iterator yearIt = years.iterator();

          // first write a file that tells us all other file names
          String infoPath = directoryName + "/" + infoFileName;
          File infoFile = new File(infoPath);
          try
          {
            FileWriter writer = new FileWriter(infoFile);
            PrintWriter out = new PrintWriter(writer);
            while (yearIt.hasNext())
            {
              out.println("" + yearIt.next());
            }

            // close the writers
            writer.close();
            out.close();
          } catch (IOException e)
          {
            fileErrorDialog.setVisible(true);
          }

          // now use social matrix class file writing
          yearIt = years.iterator();
          while (yearIt.hasNext())
          {
            int year = (Integer) (yearIt.next());
            SocialMatrix sm = altruismMatrices.get(year);
            sm.setYear(year);
            String filePath = directoryName + "/" + year + ".txt";
            File saveFile = new File(filePath);
            sm.saveSocialValuesToFileWithOverwrite(saveFile);
          }

          saveCompleteDialog.setSize(saveCompleteDialogSize);
          saveCompleteDialog.setVisible(true);
        }
      } catch (Error e)
      {
        fileErrorDialog.setVisible(true);
      }
}//GEN-LAST:event_socialValueSaveButtonActionPerformed

    private void sortByChildrenButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_sortByChildrenButtonActionPerformed
    {//GEN-HEADEREND:event_sortByChildrenButtonActionPerformed
      sortButtonsByChildren();
      getCurrentPanel().repaint();
}//GEN-LAST:event_sortByChildrenButtonActionPerformed

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
      // TODO add your handling code here:
      nullTrackersExist();
    }//GEN-LAST:event_jButton1ActionPerformed

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_jButton2ActionPerformed
    {//GEN-HEADEREND:event_jButton2ActionPerformed
      // TODO add your handling code here:
      File loadFile = new File("c:/CCPV Data/testdata.txt");
      currentAltruismMatrix.loadSocialValuesFromFile(loadFile);
    }//GEN-LAST:event_jButton2ActionPerformed

    private void setYearButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_setYearButtonActionPerformed
    {//GEN-HEADEREND:event_setYearButtonActionPerformed
      // TODO add your handling code here:
      try
      {
        currentYear = Integer.parseInt(yearTextField.getText());
        yearSet = true;
        currentAltruismMatrix = altruismMatrices.get(currentYear);
        if (currentAltruismMatrix == null)
        {
          currentAltruismMatrix = new SocialMatrix(ascriptiveTree);
          currentAltruismMatrix.setYear(currentYear);
          altruismMatrices.put(currentYear, currentAltruismMatrix);
          // start loading values from rt
          Vector<int[]> allCombos = currentAltruismMatrix.getAllCombinations();
          for (int[] source : allCombos)
          {
            for (int[] target : allCombos)
            {
              double value = rt.getAltruism(source, target, currentYear);
              currentAltruismMatrix.setAltruism(source, target, value);
            }
          }
        }
        currentAltruismMatrix.setYear(currentYear);

        // also check pop data for this year
        MultiArray<Integer> yearPop = populationCounts.get(currentYear);
        if (yearPop == null)
        {
          // set default years
          yearPop = new MultiArray<Integer>(currentAltruismMatrix.getDimensions());
          int[] dimensions = currentAltruismMatrix.getDimensions();
          System.out.println("DIMENSIONS: " + dimensions.length);
          populationCounts.put(currentYear, yearPop);

          Vector<int[]> allCombos = currentAltruismMatrix.getAllCombinations();
          for (int[] group : allCombos)
          {
            int pop = rt.getPopulation(currentYear, group);
            yearPop.setElementAtIndex(group, pop);
          }
        }

        socialValueTitle.setText("Group Altruism: " + currentYear);
        if (socialValuesSourcesSetup && socialValuesTargetsSetup && yearSet)
        {
          // need to change the drag bar panels, etc if we have a new year
          //dragBarPanels.clear();
          buttonTrackers.clear();
          tabTrackers.clear();
          // remove all but the first tab and first panel
          int totalTabCount = socialValuesTabbedPane.getTabCount();
          for (int i = 0; i < totalTabCount - 1; i++)
          {
            socialValuesTabbedPane.removeTabAt(1);
            dragBarPanels.remove(1);
          }

          socialValuesSourcesSetup = false;
          socialValuesTargetsSetup = false;
          loadSourceTreeValues();
          loadTargetTreeValues();
        }

      } catch (NumberFormatException e)
      {
        System.out.println("year not appropriate");

      }
    }//GEN-LAST:event_setYearButtonActionPerformed

    private void socialValueLoadButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_socialValueLoadButtonActionPerformed
    {//GEN-HEADEREND:event_socialValueLoadButtonActionPerformed
      // TODO add your handling code here:
      fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
      int loadVal = fileChooser.showOpenDialog(this);
      if (loadVal == JFileChooser.APPROVE_OPTION)
      {
        File socialValueLoadFile = fileChooser.getSelectedFile();
        String directoryName = socialValueLoadFile.getAbsolutePath();

        // first read the info file
        Vector<String> allFileYears = new Vector<String>();
        try
        {
          File infoFile = new File(directoryName + "/" + infoFileName);
          FileReader reader = new FileReader(infoFile);
          BufferedReader in = new BufferedReader(reader);
          String inputLine = in.readLine();
          while (inputLine != null)
          {
            allFileYears.add(inputLine);
            inputLine = in.readLine();
          }

          in.close();
          reader.close();
        } catch (IOException e)
        {
          fileErrorDialog.setVisible(true);
        }

        try
        {
          for (String s : allFileYears)
          {
            File loadFile = new File(directoryName + "/" + s + ".txt");
            System.out.println("s is: " + s);
            SocialMatrix sm = altruismMatrices.get(Integer.parseInt(s));
            if (sm != null)
            {
              sm.loadSocialValuesFromFile(loadFile);
            }
            else
            {
              sm = new SocialMatrix(ascriptiveTree);
              sm.setYear(Integer.parseInt(s));
              sm.loadSocialValuesFromFile(loadFile);
            }
          }

          moveButtonsBasedOnAltruism(getCurrentPanel(),
                  buttonTrackers.get(socialValuesTabbedPane.getSelectedIndex()),
                  tabTrackers.get(socialValuesTabbedPane.getSelectedIndex()));
        } catch (Error e)
        {
          fileErrorDialog.setVisible(true);
        }
      }
    }//GEN-LAST:event_socialValueLoadButtonActionPerformed

    private void helpButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_helpButtonActionPerformed
    {//GEN-HEADEREND:event_helpButtonActionPerformed
      // TODO add your handling code here:
      helpDialog.setVisible(true);
      helpDialog.setSize(helpDialogSize);
      helpDialog.setPreferredSize(helpDialogSize);
      System.out.println(this.getCurrentPanel().getSize());
    }//GEN-LAST:event_helpButtonActionPerformed

    private void testIndicesButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_testIndicesButtonActionPerformed
    {//GEN-HEADEREND:event_testIndicesButtonActionPerformed
      // TODO add your handling code here:
      /*
      int[] test =
      {
      1, 2, 3
      };
       */
      //this.createIndexMapForTranslation();

      try
      {
        int date = 1891;
        Vector<int[]> allCombos = currentAltruismMatrix.getAllCombinations();

        /*
        for (int[] source : allCombos)
        {
        for (int [] target : allCombos)
        {
        double robertsValue = rt.getAltruism(source, target, date);
        System.out.println("value: " + robertsValue);
        }
        }
         */

        boolean conflict = false;
        boolean nonZeroExists = false;
        for (int[] source : allCombos)
        {
          for (int[] target : allCombos)
          {
            double myValue = altruismMatrices.get(date).getSocialValue(source, target);
            double robertsValue = rt.getAltruism(source, target, date);
            //System.out.println(myValue + ", " + robertsValue);

            if (myValue != robertsValue)
            {
              conflict = true;
            }
            else
            {
              if (myValue != 0)
              {
                System.out.println("NON ZERO: ");
                Vector<String> sourceV = currentAltruismMatrix.convertIndexIntoStringVector(source);
                Vector<String> targetV = currentAltruismMatrix.convertIndexIntoStringVector(target);

                String sourceString = "";
                for (String s : sourceV)
                {
                  sourceString += s + ", ";
                }
                String targetString = "";
                for (String s : targetV)
                {
                  targetString += s + ", ";
                }

                System.out.println("source: " + sourceString);
                System.out.println("target: " + targetString);
                System.out.println("value: " + myValue);
              }
            }
          }
        }

        if (conflict)
        {
          System.out.println("CONFLICT EXISTS");
        }
        else
        {
          System.out.println("NOT ONE CONFLICT");
        }

      /*
      int index1 = randGen.nextInt(allCombos.size());
      int index2 = randGen.nextInt(allCombos.size());
      int[] group1 = allCombos.get(index1);
      int[] group2 = allCombos.get(index2);

      Vector<String> groupName1 = currentAltruismMatrix.convertIndexIntoStringVector(group1);
      String p = "";
      for (int i = 0; i < groupName1.size(); i++)
      {
      p += groupName1.get(i) + ", ";
      }
      System.out.println("GROUP 1: " + p);

      Vector<String> groupName2 = currentAltruismMatrix.convertIndexIntoStringVector(group2);
      p = "";
      for (int i = 0; i < groupName2.size(); i++)
      {
      p += groupName2.get(i) + ", ";
      }
      System.out.println("GROUP 2: " + p);

      System.out.println("MY altruism: " + altruismMatrices.get(date).getAltruism(group1, group2));
      System.out.println("ROBERTS altruism: " + rt.getAltruism(group1, group2, date));
       */
      } catch (Error e)
      {
        System.out.println("error?  caused by what?");
      }
    }//GEN-LAST:event_testIndicesButtonActionPerformed

  // Variables declaration - do not modify//GEN-BEGIN:variables
  private javax.swing.JScrollPane canvasScrollPane;
  private javax.swing.JPanel dragBarContainer;
  private javax.swing.JFileChooser fileChooser;
  private javax.swing.JDialog fileErrorDialog;
  private javax.swing.JPanel firstAltruismPanel;
  private javax.swing.JDialog groupDetailsDialog;
  private javax.swing.JButton helpButton;
  private javax.swing.JDialog helpDialog;
  private javax.swing.JTextArea instructionsTextPane;
  private javax.swing.JButton jButton1;
  private javax.swing.JButton jButton2;
  private javax.swing.JLabel jLabel1;
  private javax.swing.JLabel jLabel17;
  private javax.swing.JLabel jLabel18;
  private javax.swing.JLabel jLabel2;
  private javax.swing.JLabel jLabel21;
  private javax.swing.JLabel jLabel3;
  private javax.swing.JLabel jLabel4;
  private javax.swing.JLabel jLabel5;
  private javax.swing.JLabel jLabel6;
  private javax.swing.JLabel jLabel7;
  private javax.swing.JLabel jLabel8;
  private javax.swing.JPanel jPanel1;
  private javax.swing.JPanel jPanel2;
  private javax.swing.JPanel jPanel3;
  private javax.swing.JPanel jPanel4;
  private javax.swing.JPanel jPanel5;
  private javax.swing.JScrollPane jScrollPane1;
  private javax.swing.JScrollPane jScrollPane12;
  private javax.swing.JScrollPane jScrollPane13;
  private javax.swing.JPanel movingPanel;
  private javax.swing.JScrollPane notesContainer;
  private javax.swing.JLabel notesTitleLabel;
  private javax.swing.JDialog saveCompleteDialog;
  private javax.swing.JButton setYearButton;
  private javax.swing.JButton socialValueLoadButton;
  private javax.swing.JTextPane socialValueNotesTextPane;
  private javax.swing.JButton socialValueSaveButton;
  private javax.swing.JTree socialValueSourceTree;
  private javax.swing.JTree socialValueTargetTree;
  private javax.swing.JLabel socialValueTitle;
  private javax.swing.JTabbedPane socialValuesTabbedPane;
  private javax.swing.JButton sortByChildrenButton;
  private javax.swing.JButton testIndicesButton;
  private javax.swing.JTextField yAxisScaleInputText;
  private javax.swing.JButton yAxisScaleOKButton;
  private javax.swing.JDialog yearNotSetDialog;
  private javax.swing.JTextField yearTextField;
  // End of variables declaration//GEN-END:variables
  private int currentYear = 0;
  private HashMap<Integer, SocialMatrix> altruismMatrices = new HashMap<Integer, SocialMatrix>();
  private SocialMatrix currentAltruismMatrix;// = new SocialMatrix();
  // this is the runtime settings used to load from file
  private RunTimeSettings rt = null;
  private Vector<DragBarPanel> dragBarPanels = new Vector<DragBarPanel>();
  private Vector<Vector<SocialValueComponentTracker>> buttonTrackers = new Vector<Vector<SocialValueComponentTracker>>();
  private Vector<SocialValueComponentTracker> tabTrackers = new Vector<SocialValueComponentTracker>();
  private JTree ascriptiveTree = new JTree();
  private final Dimension DEFAULT_DRAG_BAR_CONTAINER_SIZE = new Dimension(645, 520);
  //private final Dimension DEFAULT_DRAG_BAR_CONTAINER_SIZE = new Dimension(490, 440);
  // this is the visible drag bar panel.
  private DragBarPanel theDragBarPanel = new DragBarPanel(1);
  private ExpandablePopupMenu expMenu;
  //private DefaultMutableTreeNode selectedAltruismDialogTargetCategory;
  private Component rightClickedComponentInAltruismDialog = null;
  // stores the height of the scrollbar
  private int scrollBarH = 16;
  // indicates whether the user selected anything in the altruism dialog from the trees
  private boolean socialValuesSourcesSetup = false;
  private boolean socialValuesTargetsSetup = false;
  private boolean firstTrackersSetup = false;
  private boolean settingUpNewTabs = false;
  private boolean yearSet = false;
  // announcements to tell the area expert how the altruism is
  private String neutralAltruismAnnouncement = "We have no feelings at all toward the other group.";
  private String[] positiveAltruismAnnouncements =
  {
    "We respect the other group.",
    "We will donate resources to help the other group.",
    "We accept marriages between our groups.",
    "We are strong political allies.",
    "We will die for members of the other group."
  };
  private String[] negativeAltruismAnnouncements =
  {
    "We are suspicious of the other group.",
    "We often use ethnic slurs when referring to the other group.",
    "We turn a blind eye to crimes committed against the other group.",
    "Street fights are common between our groups.",
    "We will sacrifice our own lives to destroy the other group."
  };
  private Vector<String> ascriptiveCategories = new Vector<String>();
  // stores the populations
  private HashMap<Integer, MultiArray<Integer>> populationCounts;
  // stores the wealth
  private MultiArray<Integer> wealthCounts;
  // for showing details of groups
  private GroupDetailsPanel gDP = new GroupDetailsPanel();
  // size for warning dialog
  private Dimension yearNotSetDialogSize = new Dimension(250, 100);
  private Dimension saveCompleteDialogSize = new Dimension(200, 100);
  // instructions string
  // for instructions
  private String instructions =
          "Using the sliders, please enter your perception of the level of positive or negative\n" +
          "altruism, on average, by members of the first group listed towards the second group.\n" +
          "Altruism is defined as a sense of identification and closeness that would cause a\n" +
          "member of the first group to sacrifice her/his own interests to help (positive) or\n" +
          "hurt (negative) members of the second group.  When the first and second group are the\n" +
          "same, this would indicate the average altruism felt by a member of a group to other\n" +
          "members of the same group, i.e.  a person's identification with her/his own group.\n" +
          "1 indicates very strong positive altruism, 0 indifference, and -1 very strong negative\n" +
          "altruism.    One way to think about it concretely is as follows:  Suppose a member of\n" +
          "the first group on average would be willing to pay up to $30 if this would cause\n" +
          "members of the second group to gain a total of $100.  This  would correspond to an\n" +
          "altruism of 0.3.   Suppose the member of the first group on average would be willing\n" +
          "to pay up to $15 in order to take a total of $100 away from members of the second\n" +
          "group.  This would correspond to altruism of -0.15.   Suppose a member of the first\n" +
          "group would not be willing to pay anything to change the condition of members of the\n" +
          "second group, for better or worse.  This would correspond to altruism of 0.";
  private Dimension helpDialogSize = new Dimension(630, 500);
  private Random randGen = new Random();
  // used to translate indices from mine to roberts
  private HashMap<int[], int[]> eToRIndexMap = new HashMap<int[], int[]>();
  // used to translate indices from roberts to mine
  private HashMap<int[], int[]> rToEIndexMap = new HashMap<int[], int[]>();
  private String infoFileName = "CCPV_Save_Info_DO_NOT_ALTER.txt";
}
